*/ protected $fillable = [ 'tenant_id', 'bank_name', 'account_name', 'account_number', 'iban', 'swift_code', 'is_primary', ]; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'is_primary' => 'boolean', ]; /** * Get the club that owns the bank account. */ public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } /** * Encrypt and decrypt account_number. */ protected function accountNumber(): Attribute { return Attribute::make( get: fn ($value) => $value ? Crypt::decryptString($value) : null, set: fn ($value) => $value ? Crypt::encryptString($value) : null, ); } /** * Encrypt and decrypt iban. */ protected function iban(): Attribute { return Attribute::make( get: fn ($value) => $value ? Crypt::decryptString($value) : null, set: fn ($value) => $value ? Crypt::encryptString($value) : null, ); } /** * Encrypt and decrypt swift_code. */ protected function swiftCode(): Attribute { return Attribute::make( get: fn ($value) => $value ? Crypt::decryptString($value) : null, set: fn ($value) => $value ? Crypt::encryptString($value) : null, ); } /** * Get masked account number for display. */ public function getMaskedAccountNumber(): string { $accountNumber = $this->account_number; if (!$accountNumber) { return 'N/A'; } $length = strlen($accountNumber); if ($length <= 4) { return str_repeat('*', $length); } return str_repeat('*', $length - 4) . substr($accountNumber, -4); } }