using Microsoft.EntityFrameworkCore; using PowderCoating.Core.Entities; using PowderCoating.Core.Enums; namespace PowderCoating.Infrastructure.Services; public partial class SeedDataService { /// /// Seeds a default chart of accounts for a newly onboarded company, covering all five /// standard double-entry categories: Assets, Liabilities, Equity, Revenue (with separate /// powder coating and sandblasting lines), Cost of Goods Sold, and Expenses. /// /// /// /// Idempotency: returns 0 immediately if any non-deleted accounts already exist for this /// company, so re-running seed does not produce duplicate account numbers. /// /// /// Several accounts are marked IsSystem = true (Checking, AR, AP, and main Powder /// Coating Revenue). System accounts are referenced by account number in other seeders /// (e.g. SeedInvoicesAsync looks up account "4000" for invoice line items) and /// should not be renamed or deleted by end users. /// /// /// Account numbers follow a conventional small-business numbering scheme: /// 1xxx = Assets, 2xxx = Liabilities, 3xxx = Equity, 4xxx = Revenue, /// 5xxx = Cost of Goods Sold, 6xxx = Expenses. This makes the chart immediately /// recognisable to accountants without custom configuration. /// /// /// The tenant company to seed the chart of accounts for. /// Number of account records inserted, or 0 if already seeded. private async Task SeedDefaultChartOfAccountsAsync(Company company) { var existingCount = await _context.Set() .IgnoreQueryFilters() .CountAsync(a => a.CompanyId == company.Id && !a.IsDeleted); if (existingCount > 0) return 0; // Already seeded var now = DateTime.UtcNow; var accounts = new List { // ── ASSETS ──────────────────────────────────────────────────────── new Account { AccountNumber = "1000", Name = "Checking Account", AccountType = AccountType.Asset, AccountSubType = AccountSubType.Checking, IsSystem = true, IsActive = true, Description = "Primary business checking account", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "1010", Name = "Savings Account", AccountType = AccountType.Asset, AccountSubType = AccountSubType.Savings, IsSystem = false, IsActive = true, Description = "Business savings account", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "1100", Name = "Accounts Receivable", AccountType = AccountType.Asset, AccountSubType = AccountSubType.AccountsReceivable, IsSystem = true, IsActive = true, Description = "Amounts owed by customers for services", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "1200", Name = "Inventory - Powder", AccountType = AccountType.Asset, AccountSubType = AccountSubType.Inventory, IsSystem = false, IsActive = true, Description = "Powder coating materials in stock", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "1210", Name = "Inventory - Consumables", AccountType = AccountType.Asset, AccountSubType = AccountSubType.Inventory, IsSystem = false, IsActive = true, Description = "Masking, tape, and other consumables", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "1300", Name = "Equipment", AccountType = AccountType.Asset, AccountSubType = AccountSubType.FixedAsset, IsSystem = false, IsActive = true, Description = "Ovens, booths, sandblasters, and equipment", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "1310", Name = "Accumulated Depreciation", AccountType = AccountType.Asset, AccountSubType = AccountSubType.FixedAsset, IsSystem = false, IsActive = true, Description = "Accumulated depreciation on equipment", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "1400", Name = "Prepaid Expenses", AccountType = AccountType.Asset, AccountSubType = AccountSubType.OtherCurrentAsset, IsSystem = false, IsActive = true, Description = "Prepaid insurance, rent, and other items", CompanyId = company.Id, CreatedAt = now }, // ── LIABILITIES ─────────────────────────────────────────────────── new Account { AccountNumber = "2000", Name = "Accounts Payable", AccountType = AccountType.Liability, AccountSubType = AccountSubType.AccountsPayable, IsSystem = true, IsActive = true, Description = "Amounts owed to suppliers and vendors", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "2100", Name = "Credit Card Payable", AccountType = AccountType.Liability, AccountSubType = AccountSubType.CreditCard, IsSystem = false, IsActive = true, Description = "Business credit card balance", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "2200", Name = "Sales Tax Payable", AccountType = AccountType.Liability, AccountSubType = AccountSubType.OtherCurrentLiability, IsSystem = false, IsActive = true, Description = "Sales tax collected and owed to government", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "2300", Name = "Payroll Liabilities", AccountType = AccountType.Liability, AccountSubType = AccountSubType.OtherCurrentLiability, IsSystem = false, IsActive = true, Description = "Payroll taxes and withholdings owed", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "2900", Name = "Business Loan", AccountType = AccountType.Liability, AccountSubType = AccountSubType.LongTermLiability, IsSystem = false, IsActive = true, Description = "Long-term equipment or business loan", CompanyId = company.Id, CreatedAt = now }, // ── EQUITY ──────────────────────────────────────────────────────── new Account { AccountNumber = "3000", Name = "Owner's Equity", AccountType = AccountType.Equity, AccountSubType = AccountSubType.OwnersEquity, IsSystem = false, IsActive = true, Description = "Owner's invested capital", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "3100", Name = "Retained Earnings", AccountType = AccountType.Equity, AccountSubType = AccountSubType.RetainedEarnings, IsSystem = false, IsActive = true, Description = "Cumulative net income retained in business", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "3200", Name = "Owner's Draw", AccountType = AccountType.Equity, AccountSubType = AccountSubType.OwnersEquity, IsSystem = false, IsActive = true, Description = "Withdrawals by owner", CompanyId = company.Id, CreatedAt = now }, // ── REVENUE ─────────────────────────────────────────────────────── new Account { AccountNumber = "4000", Name = "Powder Coating Revenue", AccountType = AccountType.Revenue, AccountSubType = AccountSubType.Sales, IsSystem = true, IsActive = true, Description = "Revenue from powder coating services", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "4100", Name = "Sandblasting Revenue", AccountType = AccountType.Revenue, AccountSubType = AccountSubType.ServiceRevenue, IsSystem = false, IsActive = true, Description = "Revenue from sandblasting services", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "4200", Name = "Other Service Revenue", AccountType = AccountType.Revenue, AccountSubType = AccountSubType.ServiceRevenue, IsSystem = false, IsActive = true, Description = "Revenue from other shop services", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "4900", Name = "Other Income", AccountType = AccountType.Revenue, AccountSubType = AccountSubType.OtherIncome, IsSystem = false, IsActive = true, Description = "Miscellaneous income", CompanyId = company.Id, CreatedAt = now }, // ── COST OF GOODS SOLD ──────────────────────────────────────────── new Account { AccountNumber = "5000", Name = "Cost of Goods Sold", AccountType = AccountType.CostOfGoods, AccountSubType = AccountSubType.CostOfGoodsSold, IsSystem = false, IsActive = true, Description = "Direct cost of services delivered", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "5100", Name = "Powder & Materials", AccountType = AccountType.CostOfGoods, AccountSubType = AccountSubType.CostOfGoodsSold, IsSystem = false, IsActive = true, Description = "Powder coatings and direct materials used", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "5200", Name = "Consumables & Shop Supplies", AccountType = AccountType.CostOfGoods, AccountSubType = AccountSubType.CostOfGoodsSold, IsSystem = false, IsActive = true, Description = "Masking, tape, and other job supplies", CompanyId = company.Id, CreatedAt = now }, // ── EXPENSES ────────────────────────────────────────────────────── new Account { AccountNumber = "6000", Name = "Advertising & Marketing", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Advertising, IsSystem = false, IsActive = true, Description = "Advertising, marketing, and promotions", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6100", Name = "Equipment & Repairs", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Equipment, IsSystem = false, IsActive = true, Description = "Equipment maintenance and repair costs", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6200", Name = "Insurance", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Insurance, IsSystem = false, IsActive = true, Description = "Business, liability, and equipment insurance", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6300", Name = "Payroll & Labor", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Payroll, IsSystem = false, IsActive = true, Description = "Wages, salaries, and payroll taxes", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6400", Name = "Professional Fees", AccountType = AccountType.Expense, AccountSubType = AccountSubType.ProfessionalFees, IsSystem = false, IsActive = true, Description = "Accounting, legal, and consulting fees", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6500", Name = "Rent & Facilities", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Rent, IsSystem = false, IsActive = true, Description = "Shop rent and facility costs", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6600", Name = "Utilities", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Utilities, IsSystem = false, IsActive = true, Description = "Electric, gas, water, and internet", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6700", Name = "Vehicle & Transportation", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Vehicle, IsSystem = false, IsActive = true, Description = "Fuel, vehicle maintenance, and transport", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6800", Name = "Office Supplies", AccountType = AccountType.Expense, AccountSubType = AccountSubType.OfficeSupplies, IsSystem = false, IsActive = true, Description = "General office and administrative supplies", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6900", Name = "Bank Charges & Fees", AccountType = AccountType.Expense, AccountSubType = AccountSubType.BankCharges, IsSystem = false, IsActive = true, Description = "Bank fees, merchant processing, and wire fees", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6950", Name = "Depreciation Expense", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Depreciation, IsSystem = false, IsActive = true, Description = "Depreciation on fixed assets", CompanyId = company.Id, CreatedAt = now }, new Account { AccountNumber = "6990", Name = "Other Expenses", AccountType = AccountType.Expense, AccountSubType = AccountSubType.Other, IsSystem = false, IsActive = true, Description = "Miscellaneous business expenses", CompanyId = company.Id, CreatedAt = now }, }; await _context.Set().AddRangeAsync(accounts); await _context.SaveChangesAsync(); return accounts.Count; } }