Files
AFC-Demo/app/Models/Transaction.php
T

96 lines
2.8 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Transaction extends Model
{
use HasFactory;
public const STATUS_TRUE_POSITIVE = 'true_positive';
public const STATUS_FALSE_POSITIVE = 'false_positive';
public const STATUS_CLEARED = 'cleared';
/**
* Disable mass assignment protection to allow JSONB columns
*
* @var array<int, string>
*/
protected $guarded = [];
/**
* Cached JSONB column casts to avoid repeated schema queries
*/
private static ?array $jsonbCasts = null;
/**
* Get the attributes that should be cast.
*
* Dynamically casts all JSONB columns (102 output_keys) as arrays
* Uses static caching to avoid repeated database schema queries
*
* @return array<string, string>
*/
protected function casts(): array
{
// Return cached casts if available
if (self::$jsonbCasts !== null) {
return self::$jsonbCasts;
}
$standardCasts = [
'executed_at' => 'datetime',
'requires_review' => 'boolean',
'signals' => 'array',
];
// Standard non-JSONB columns
$standardColumns = [
'id', 'company_id', 'reference', 'amount', 'currency',
'counterparty', 'counterparty_country', 'channel', 'executed_at',
'risk_score', 'status', 'requires_review', 'flagged_by',
'flagged_reason', 'signals', 'created_at', 'updated_at',
];
try {
// Get all columns from the database (only once per request)
$allColumns = \Illuminate\Support\Facades\Schema::getColumnListing('transactions');
// All remaining columns are JSONB columns that should be cast as arrays
$jsonbColumns = array_diff($allColumns, $standardColumns);
foreach ($jsonbColumns as $column) {
$standardCasts[$column] = 'array';
}
} catch (\Exception $e) {
// If schema query fails (e.g., during migrations), just use standard casts
\Illuminate\Support\Facades\Log::warning('Failed to load JSONB column casts: ' . $e->getMessage());
}
// Cache for subsequent calls
self::$jsonbCasts = $standardCasts;
return self::$jsonbCasts;
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public function statusLabel(): string
{
return match ($this->status) {
self::STATUS_TRUE_POSITIVE => __('Kritisches Risiko'),
self::STATUS_FALSE_POSITIVE => __('Hohes Risiko'),
self::STATUS_CLEARED => __('Geringes Risiko'),
default => __('Unbekanntes Risiko'),
};
}
}