webmoney/backend/app/Models/Account.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;
}
}