#ifndef TRANSACTION_H #define TRANSACTION_H #include #include #include enum class TransactionType { Estimated, Actual, Reconciliation }; enum class RecurrenceFrequency { None, Daily, Weekly, BiWeekly, Monthly, Yearly }; struct Transaction { int id; QDate date; double amount; QString account; QString category; QString description; TransactionType type; int recurringId; // -1 if not part of recurring series int sortOrder; // For ordering on same date bool reconciled; // true if converted from projection to actual QString occurrenceKey; // e.g. "2025-01" for monthly, "2025-W03" for weekly double expectedAmount; // original projected amount (for variance tracking) QDate expectedDate; // original projected date (for variance tracking) double expectedBalance; // for reconciliation checkpoints - what bank says double calculatedBalance; // for reconciliation checkpoints - what we calculated Transaction() : id(-1), amount(0.0), type(TransactionType::Estimated), recurringId(-1), sortOrder(0), reconciled(false), expectedAmount(0.0), expectedBalance(0.0), calculatedBalance(0.0) {} double getBalance() const { return amount; } }; struct RecurringRule { int id; QString name; RecurrenceFrequency frequency; QDate startDate; QDate endDate; // Can be null for indefinite double amount; QString account; QString category; QString description; int dayOfWeek; // 1-7 for weekly (1=Monday), -1 if not applicable int dayOfMonth; // 1-31 for monthly, -1 if not applicable int occurrences; // Number of times to repeat, -1 for indefinite int sortOrder; // For ordering transactions on same date QDate projectionEndDate; // How far into future to generate projections RecurringRule() : id(-1), frequency(RecurrenceFrequency::None), amount(0.0), dayOfWeek(-1), dayOfMonth(-1), occurrences(-1), sortOrder(0) {} }; // Register Transaction for use in QVariant Q_DECLARE_METATYPE(Transaction) #endif // TRANSACTION_H