153 lines
3.9 KiB
PHP
153 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class Account extends Model
|
|
{
|
|
use HasFactory, SoftDeletes;
|
|
|
|
/**
|
|
* Tipos de conta disponíveis
|
|
*/
|
|
public const TYPE_CASH = 'cash';
|
|
public const TYPE_CHECKING = 'checking';
|
|
public const TYPE_SAVINGS = 'savings';
|
|
public const TYPE_CREDIT_CARD = 'credit_card';
|
|
public const TYPE_ASSET = 'asset';
|
|
public const TYPE_LIABILITY = 'liability';
|
|
|
|
public const TYPES = [
|
|
self::TYPE_CASH => 'Dinheiro',
|
|
self::TYPE_CHECKING => 'Conta Corrente',
|
|
self::TYPE_SAVINGS => 'Poupança',
|
|
self::TYPE_CREDIT_CARD => 'Cartão de Crédito',
|
|
self::TYPE_ASSET => 'Ativo',
|
|
self::TYPE_LIABILITY => 'Passivo',
|
|
];
|
|
|
|
protected $fillable = [
|
|
'user_id',
|
|
'name',
|
|
'type',
|
|
'bank_name',
|
|
'account_number',
|
|
'initial_balance',
|
|
'current_balance',
|
|
'credit_limit',
|
|
'currency',
|
|
'color',
|
|
'icon',
|
|
'description',
|
|
'is_active',
|
|
'include_in_total',
|
|
];
|
|
|
|
protected $casts = [
|
|
'initial_balance' => 'decimal:2',
|
|
'current_balance' => 'decimal:2',
|
|
'credit_limit' => 'decimal:2',
|
|
'is_active' => 'boolean',
|
|
'include_in_total' => 'boolean',
|
|
];
|
|
|
|
/**
|
|
* Relação com o usuário
|
|
*/
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
/**
|
|
* Scope para contas ativas
|
|
*/
|
|
public function scopeActive($query)
|
|
{
|
|
return $query->where('is_active', true);
|
|
}
|
|
|
|
/**
|
|
* Scope para contas de um tipo específico
|
|
*/
|
|
public function scopeOfType($query, string $type)
|
|
{
|
|
return $query->where('type', $type);
|
|
}
|
|
|
|
/**
|
|
* Scope para contas que devem ser incluídas no saldo total
|
|
*/
|
|
public function scopeIncludeInTotal($query)
|
|
{
|
|
return $query->where('include_in_total', true);
|
|
}
|
|
|
|
/**
|
|
* Retorna o nome legível do tipo de conta
|
|
*/
|
|
public function getTypeNameAttribute(): string
|
|
{
|
|
return self::TYPES[$this->type] ?? $this->type;
|
|
}
|
|
|
|
/**
|
|
* Verifica se é uma conta de crédito (cartão ou passivo)
|
|
*/
|
|
public function isCreditAccount(): bool
|
|
{
|
|
return in_array($this->type, [self::TYPE_CREDIT_CARD, self::TYPE_LIABILITY]);
|
|
}
|
|
|
|
/**
|
|
* Calcula o saldo disponível (para cartões de crédito)
|
|
*/
|
|
public function getAvailableBalanceAttribute(): float
|
|
{
|
|
if ($this->type === self::TYPE_CREDIT_CARD && $this->credit_limit) {
|
|
return (float) $this->credit_limit + (float) $this->current_balance;
|
|
}
|
|
return (float) $this->current_balance;
|
|
}
|
|
|
|
/**
|
|
* Relação com transações
|
|
*/
|
|
public function transactions()
|
|
{
|
|
return $this->hasMany(Transaction::class);
|
|
}
|
|
|
|
/**
|
|
* Recalcula o saldo atual baseado nas transações efetivadas
|
|
*/
|
|
public function recalculateBalance(): float
|
|
{
|
|
$initialBalance = (float) $this->initial_balance;
|
|
|
|
// Soma de créditos (transações efetivadas)
|
|
$credits = $this->transactions()
|
|
->where('type', 'credit')
|
|
->where('status', 'completed')
|
|
->sum('amount');
|
|
|
|
// Soma de débitos (transações efetivadas)
|
|
$debits = $this->transactions()
|
|
->where('type', 'debit')
|
|
->where('status', 'completed')
|
|
->sum('amount');
|
|
|
|
// Saldo = Saldo Inicial + Créditos - Débitos
|
|
$newBalance = $initialBalance + (float) $credits - (float) $debits;
|
|
|
|
// Atualizar no banco
|
|
$this->update(['current_balance' => $newBalance]);
|
|
|
|
return $newBalance;
|
|
}
|
|
}
|