42eff3357e
- RecurringTemplate entity with Frequency/IntervalCount/NextFireDate/EndDate/MaxOccurrences/TemplateData JSON - RecurringFrequency + RecurringTemplateType enums - RecurringTransactionService BackgroundService: hourly check, creates Draft bills or immediate expenses, advances NextFireDate, auto-deactivates on limits - RecurringTemplatesController: Index/Create/Edit/ToggleActive/Delete/GenerateNow (on-demand fire) - Three views + external JS for type-toggle and dynamic bill line items - Finance sidebar nav: Recurring Transactions - Migration: AddRecurringTemplates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
172 lines
7.1 KiB
C#
172 lines
7.1 KiB
C#
using PowderCoating.Core.Entities;
|
|
using PowderCoating.Core.Interfaces.Repositories;
|
|
|
|
namespace PowderCoating.Core.Interfaces;
|
|
|
|
public interface IUnitOfWork : IDisposable
|
|
{
|
|
// Multi-tenancy
|
|
IRepository<Company> Companies { get; }
|
|
IRepository<CompanyOperatingCosts> CompanyOperatingCosts { get; }
|
|
IRepository<CompanyPreferences> CompanyPreferences { get; }
|
|
IRepository<CompanySmsAgreement> CompanySmsAgreements { get; }
|
|
|
|
// AI Predictions
|
|
IRepository<AiItemPrediction> AiItemPredictions { get; }
|
|
|
|
// Powder Insights
|
|
IPowderUsageLogRepository PowderUsageLogs { get; }
|
|
|
|
// Core entities — typed repositories for complex domains
|
|
ICustomerRepository Customers { get; }
|
|
IJobRepository Jobs { get; }
|
|
IRepository<JobDailyPriority> JobDailyPriorities { get; }
|
|
IRepository<JobItem> JobItems { get; }
|
|
IJobItemCoatRepository JobItemCoats { get; }
|
|
IRepository<JobItemPrepService> JobItemPrepServices { get; }
|
|
IRepository<JobChangeHistory> JobChangeHistories { get; }
|
|
IRepository<JobPrepService> JobPrepServices { get; }
|
|
IQuoteRepository Quotes { get; }
|
|
IRepository<QuotePhoto> QuotePhotos { get; }
|
|
IRepository<QuoteItem> QuoteItems { get; }
|
|
IRepository<QuoteItemCoat> QuoteItemCoats { get; }
|
|
IRepository<QuoteItemPrepService> QuoteItemPrepServices { get; }
|
|
IRepository<QuoteChangeHistory> QuoteChangeHistories { get; }
|
|
IRepository<InventoryItem> InventoryItems { get; }
|
|
IPlainRepository<PowderCatalogItem> PowderCatalog { get; }
|
|
IInventoryTransactionRepository InventoryTransactions { get; }
|
|
IRepository<Equipment> Equipment { get; }
|
|
IRepository<OvenCost> OvenCosts { get; }
|
|
IRepository<CompanyBlastSetup> BlastSetups { get; }
|
|
IRepository<MaintenanceRecord> MaintenanceRecords { get; }
|
|
IRepository<Vendor> Vendors { get; }
|
|
IJobPhotoRepository JobPhotos { get; }
|
|
IRepository<JobNote> JobNotes { get; }
|
|
IRepository<CustomerNote> CustomerNotes { get; }
|
|
IRepository<JobStatusHistory> JobStatusHistory { get; }
|
|
IRepository<PricingTier> PricingTiers { get; }
|
|
|
|
// Lookup tables (replacing enums)
|
|
IRepository<JobStatusLookup> JobStatusLookups { get; }
|
|
IRepository<JobPriorityLookup> JobPriorityLookups { get; }
|
|
IRepository<QuoteStatusLookup> QuoteStatusLookups { get; }
|
|
IRepository<InventoryCategoryLookup> InventoryCategoryLookups { get; }
|
|
IRepository<AppointmentStatusLookup> AppointmentStatusLookups { get; }
|
|
IRepository<AppointmentTypeLookup> AppointmentTypeLookups { get; }
|
|
IRepository<PrepService> PrepServices { get; }
|
|
IRepository<ShopWorker> ShopWorkers { get; }
|
|
IRepository<ShopWorkerRoleCost> ShopWorkerRoleCosts { get; }
|
|
IRepository<ReworkRecord> ReworkRecords { get; }
|
|
IRepository<Refund> Refunds { get; }
|
|
IRepository<CreditMemo> CreditMemos { get; }
|
|
IRepository<CreditMemoApplication> CreditMemoApplications { get; }
|
|
IRepository<JobTimeEntry> JobTimeEntries { get; }
|
|
|
|
// Appointments
|
|
IRepository<Appointment> Appointments { get; }
|
|
|
|
// Product Catalog
|
|
IRepository<CatalogCategory> CatalogCategories { get; }
|
|
IRepository<CatalogItem> CatalogItems { get; }
|
|
IRepository<CatalogPriceCheckReport> CatalogPriceCheckReports { get; }
|
|
|
|
// Oven Scheduling
|
|
IRepository<OvenBatch> OvenBatches { get; }
|
|
IRepository<OvenBatchItem> OvenBatchItems { get; }
|
|
|
|
// Invoices, Payments & Deposits — typed repository for complex include chains
|
|
IInvoiceRepository Invoices { get; }
|
|
IRepository<InvoiceItem> InvoiceItems { get; }
|
|
IRepository<Payment> Payments { get; }
|
|
IRepository<Deposit> Deposits { get; }
|
|
|
|
// Purchase Orders — typed repository for paged/filtered list and detail load
|
|
IPurchaseOrderRepository PurchaseOrders { get; }
|
|
IRepository<PurchaseOrderItem> PurchaseOrderItems { get; }
|
|
|
|
// Expense Tracking / Accounts Payable — typed repository for Bills
|
|
IRepository<Account> Accounts { get; }
|
|
IBillRepository Bills { get; }
|
|
IRepository<BillLineItem> BillLineItems { get; }
|
|
IRepository<BillPayment> BillPayments { get; }
|
|
IRepository<Expense> Expenses { get; }
|
|
|
|
// Manual Journal Entries
|
|
IRepository<JournalEntry> JournalEntries { get; }
|
|
IRepository<JournalEntryLine> JournalEntryLines { get; }
|
|
|
|
// Vendor Credits
|
|
IRepository<VendorCredit> VendorCredits { get; }
|
|
IRepository<VendorCreditLineItem> VendorCreditLineItems { get; }
|
|
IRepository<VendorCreditApplication> VendorCreditApplications { get; }
|
|
|
|
// Bank Reconciliation
|
|
IRepository<BankReconciliation> BankReconciliations { get; }
|
|
|
|
// Tax Rates
|
|
IRepository<TaxRate> TaxRates { get; }
|
|
|
|
// Recurring Transactions
|
|
IRepository<RecurringTemplate> RecurringTemplates { get; }
|
|
|
|
// Notifications — typed repository for IgnoreQueryFilters-based history lookups
|
|
INotificationLogRepository NotificationLogs { get; }
|
|
IRepository<NotificationTemplate> NotificationTemplates { get; }
|
|
|
|
// Subscription
|
|
IRepository<SubscriptionPlanConfig> SubscriptionPlanConfigs { get; }
|
|
|
|
// Job Templates
|
|
IJobTemplateRepository JobTemplates { get; }
|
|
IRepository<JobTemplateItem> JobTemplateItems { get; }
|
|
IRepository<JobTemplateItemCoat> JobTemplateItemCoats { get; }
|
|
IRepository<JobTemplateItemPrepService> JobTemplateItemPrepServices { get; }
|
|
|
|
// Platform content (SuperAdmin-managed, no tenant filter, no soft delete)
|
|
IPlainRepository<Announcement> Announcements { get; }
|
|
IPlainRepository<BannedIp> BannedIps { get; }
|
|
IPlainRepository<DashboardTip> DashboardTips { get; }
|
|
IRepository<InAppNotification> InAppNotifications { get; }
|
|
IPlainRepository<ReleaseNote> ReleaseNotes { get; }
|
|
|
|
// Bug Reports
|
|
IRepository<BugReport> BugReports { get; }
|
|
IRepository<BugReportAttachment> BugReportAttachments { get; }
|
|
|
|
// Contact Us
|
|
IRepository<ContactSubmission> ContactSubmissions { get; }
|
|
|
|
// AI lookup: per-manufacturer URL patterns
|
|
IRepository<ManufacturerLookupPattern> ManufacturerLookupPatterns { get; }
|
|
|
|
// Gift Certificates
|
|
IRepository<GiftCertificate> GiftCertificates { get; }
|
|
IRepository<GiftCertificateRedemption> GiftCertificateRedemptions { get; }
|
|
|
|
Task<int> SaveChangesAsync();
|
|
Task<int> CompleteAsync(); // Alias for SaveChangesAsync
|
|
|
|
/// <summary>
|
|
/// Executes <paramref name="operation"/> inside a database transaction using EF Core's
|
|
/// execution strategy, enabling compatibility with SqlServerRetryingExecutionStrategy.
|
|
/// Commits on success and rolls back on any exception (which is re-thrown).
|
|
/// </summary>
|
|
Task ExecuteInTransactionAsync(Func<Task> operation);
|
|
|
|
/// <summary>
|
|
/// Same as <see cref="ExecuteInTransactionAsync(Func{Task})"/> but returns a value.
|
|
/// </summary>
|
|
Task<T> ExecuteInTransactionAsync<T>(Func<Task<T>> operation);
|
|
|
|
/// <summary>
|
|
/// Detaches all tracked entities from the change tracker.
|
|
/// Use after a failed save to prevent contaminating subsequent operations.
|
|
/// </summary>
|
|
void ClearChangeTracker();
|
|
|
|
// Kept for backwards-compatibility — prefer ExecuteInTransactionAsync for new code.
|
|
Task BeginTransactionAsync();
|
|
Task CommitTransactionAsync();
|
|
Task RollbackTransactionAsync();
|
|
}
|