230 lines
5.9 KiB
PHP
230 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Repositories;
|
|
|
|
use App\Models\Backend\Transaction;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class TransactionRepository
|
|
{
|
|
/**
|
|
* Alle Transaktionen mit Outputs
|
|
*/
|
|
public function all(): Collection
|
|
{
|
|
return Transaction::with('outputs')
|
|
->orderBy('created_at', 'desc')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Finde Transaction by ID mit Outputs
|
|
*/
|
|
public function find(int $id): ?Transaction
|
|
{
|
|
return Transaction::with('outputs')->find($id);
|
|
}
|
|
|
|
/**
|
|
* Transaktionen die Review benötigen
|
|
*/
|
|
public function requiresReview(): Collection
|
|
{
|
|
return Transaction::with('outputs')
|
|
->where('status', Transaction::STATUS_COMPLETED)
|
|
->get()
|
|
->filter(fn ($t) => $t->requiresReview());
|
|
}
|
|
|
|
/**
|
|
* High-Risk Transaktionen
|
|
*/
|
|
public function highRisk(int $threshold = 70): Collection
|
|
{
|
|
return $this->all()
|
|
->filter(function ($transaction) use ($threshold) {
|
|
$risk = $transaction->getRiskAssessment();
|
|
|
|
return ($risk['score'] ?? 0) >= $threshold;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Transaktionen nach Firma
|
|
*/
|
|
public function byCompany(string $companyName): Collection
|
|
{
|
|
return Transaction::with('outputs')
|
|
->where('corporate_entity', 'ILIKE', "%{$companyName}%")
|
|
->orderBy('tx_date', 'desc')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Transaktionen nach Status
|
|
*/
|
|
public function byStatus(string $status): Collection
|
|
{
|
|
return Transaction::with('outputs')
|
|
->where('status', $status)
|
|
->orderBy('created_at', 'desc')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Pending Transaktionen (warten auf KI-Verarbeitung)
|
|
*/
|
|
public function pending(): Collection
|
|
{
|
|
return $this->byStatus(Transaction::STATUS_PENDING);
|
|
}
|
|
|
|
/**
|
|
* Processing Transaktionen (werden gerade verarbeitet)
|
|
*/
|
|
public function processing(): Collection
|
|
{
|
|
return $this->byStatus(Transaction::STATUS_PROCESSING);
|
|
}
|
|
|
|
/**
|
|
* Completed Transaktionen
|
|
*/
|
|
public function completed(): Collection
|
|
{
|
|
return $this->byStatus(Transaction::STATUS_COMPLETED);
|
|
}
|
|
|
|
/**
|
|
* Failed Transaktionen
|
|
*/
|
|
public function failed(): Collection
|
|
{
|
|
return $this->byStatus(Transaction::STATUS_FAILED);
|
|
}
|
|
|
|
/**
|
|
* Statistiken
|
|
*/
|
|
public function stats(): array
|
|
{
|
|
$total = Transaction::count();
|
|
$pending = Transaction::where('status', Transaction::STATUS_PENDING)->count();
|
|
$processing = Transaction::where('status', Transaction::STATUS_PROCESSING)->count();
|
|
$completed = Transaction::where('status', Transaction::STATUS_COMPLETED)->count();
|
|
$failed = Transaction::where('status', Transaction::STATUS_FAILED)->count();
|
|
|
|
// Review Statistics
|
|
$needsReview = $this->completed()
|
|
->filter(fn ($t) => $t->requiresReview())
|
|
->count();
|
|
|
|
// Risk Statistics
|
|
$highRisk = $this->completed()
|
|
->filter(fn ($t) => $t->getRiskScore() >= 70)
|
|
->count();
|
|
|
|
$mediumRisk = $this->completed()
|
|
->filter(fn ($t) => $t->getRiskScore() >= 40 && $t->getRiskScore() < 70)
|
|
->count();
|
|
|
|
$lowRisk = $this->completed()
|
|
->filter(fn ($t) => $t->getRiskScore() < 40)
|
|
->count();
|
|
|
|
return compact(
|
|
'total',
|
|
'pending',
|
|
'processing',
|
|
'completed',
|
|
'failed',
|
|
'needsReview',
|
|
'highRisk',
|
|
'mediumRisk',
|
|
'lowRisk'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Paginierte Transaktionen
|
|
*/
|
|
public function paginated(int $perPage = 20)
|
|
{
|
|
return Transaction::with('outputs')
|
|
->orderBy('created_at', 'desc')
|
|
->paginate($perPage);
|
|
}
|
|
|
|
/**
|
|
* Suche in Transaktionen
|
|
*/
|
|
public function search(string $query): Collection
|
|
{
|
|
return Transaction::with('outputs')
|
|
->where(function ($q) use ($query) {
|
|
$q->where('corporate_entity', 'ILIKE', "%{$query}%")
|
|
->orWhere('corporate_counterparty', 'ILIKE', "%{$query}%")
|
|
->orWhere('tx_purpose', 'ILIKE', "%{$query}%");
|
|
})
|
|
->orderBy('created_at', 'desc')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Transaktionen nach Datum-Range
|
|
*/
|
|
public function byDateRange(string $startDate, string $endDate): Collection
|
|
{
|
|
return Transaction::with('outputs')
|
|
->whereBetween('tx_date', [$startDate, $endDate])
|
|
->orderBy('tx_date', 'desc')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Alle unique Firmen
|
|
*/
|
|
public function getAllCompanies(): Collection
|
|
{
|
|
return DB::connection('backend')
|
|
->table('transactions')
|
|
->select('corporate_entity')
|
|
->distinct()
|
|
->orderBy('corporate_entity')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Dashboard-Daten
|
|
*/
|
|
public function dashboardData(): array
|
|
{
|
|
$stats = $this->stats();
|
|
|
|
$recentTransactions = Transaction::with('outputs')
|
|
->orderBy('created_at', 'desc')
|
|
->limit(10)
|
|
->get();
|
|
|
|
$recentHighRisk = $this->completed()
|
|
->filter(fn ($t) => $t->getRiskScore() >= 70)
|
|
->take(5);
|
|
|
|
$topCompanies = DB::connection('backend')
|
|
->table('transactions')
|
|
->select('corporate_entity', DB::raw('COUNT(*) as count'))
|
|
->groupBy('corporate_entity')
|
|
->orderByDesc('count')
|
|
->limit(10)
|
|
->get();
|
|
|
|
return [
|
|
'stats' => $stats,
|
|
'recent_transactions' => $recentTransactions,
|
|
'recent_high_risk' => $recentHighRisk,
|
|
'top_companies' => $topCompanies,
|
|
];
|
|
}
|
|
}
|