EntryType::class, 'amount_minor' => 'integer', 'balance_after_minor' => 'integer', ]; public $timestamps = false; // created_at only, set via useCurrent() // ── Relationships ── public function transaction() { return $this->belongsTo(Transaction::class); } public function wallet() { return $this->belongsTo(Wallet::class); } // ── Scopes ── public function scopeDebits($query) { return $query->where('entry_type', EntryType::DEBIT); } public function scopeCredits($query) { return $query->where('entry_type', EntryType::CREDIT); } public function scopeForWallet($query, int $walletId) { return $query->where('wallet_id', $walletId); } // ── Reconciliation helper ── /** * Verify double-entry integrity: SUM(debits) must equal SUM(credits) * for the given transaction_id. */ public static function verifyIntegrity(int $transactionId): bool { $debits = self::where('transaction_id', $transactionId)->debits()->sum('amount_minor'); $credits = self::where('transaction_id', $transactionId)->credits()->sum('amount_minor'); return $debits === $credits && $debits > 0; } }