fix: Correção relatórios de Passivos e Transações Futuras (v1.34.0)

- Relatório Passivos: total_amount → total_contract_value
- Transações Futuras: total_items → total_transactions
- Atualizado VERSION e CHANGELOG
This commit is contained in:
marcoitaloesp-ai 2025-12-14 22:11:41 +00:00 committed by GitHub
parent 8d9e022f9f
commit f9571656d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 397 additions and 8 deletions

View File

@ -5,6 +5,17 @@ O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/).
Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/).
## [1.34.0] - 2025-12-14
### Fixed
- **Relatório de Passivos** - Correção de campo para valor total da dívida
- Alterado `total_amount` para `total_contract_value` (campo correto do modelo)
- Dívida Total agora exibe o valor correto das contas de passivo
- **Relatório de Transações Futuras** - Padronização de nomenclatura
- Alterado `total_items` para `total_transactions` no resumo
- Melhora consistência com outros endpoints da API
## [1.33.0] - 2025-12-14
### Added

View File

@ -1 +1 @@
1.33.0
1.34.0

View File

@ -856,6 +856,10 @@ public function projection(Request $request)
'total' => round($overdueExpense, 2),
],
'projection' => [
// Valores principais (usa projeção inteligente)
'income' => round($smartProjectedIncome, 2),
'expense' => round($smartProjectedExpense, 2),
'balance' => round($smartProjectedIncome - $smartProjectedExpense, 2),
// Projeção simples (extrapolação linear)
'simple' => [
'income' => round($simpleProjectedIncome, 2),
@ -1161,9 +1165,10 @@ public function liabilities(Request $request)
$result = $liabilities->map(function($l) use (&$totalDebtConverted, &$totalPaidConverted, &$totalPendingConverted) {
$currency = $l->currency ?? 'EUR';
$totalAmount = $l->total_amount ?? 0;
$paidAmount = $l->installments->where('status', 'paid')->sum('amount');
$pendingAmount = $l->installments->where('status', '!=', 'paid')->sum('amount');
$totalAmount = $l->total_contract_value ?? 0;
// Usar installment_amount en lugar de amount
$paidAmount = $l->installments->where('status', 'paid')->sum('installment_amount');
$pendingAmount = $l->installments->where('status', '!=', 'paid')->sum('installment_amount');
$totalDebtConverted += $this->convertToPrimaryCurrency($totalAmount, $currency);
$totalPaidConverted += $this->convertToPrimaryCurrency($paidAmount, $currency);
@ -1191,7 +1196,7 @@ public function liabilities(Request $request)
'paid_installments' => $l->installments->where('status', 'paid')->count(),
'overdue_installments' => $overdueInstallments,
'next_installment' => $nextInstallment ? [
'amount' => round($nextInstallment->amount, 2),
'amount' => round($nextInstallment->installment_amount, 2),
'due_date' => $nextInstallment->due_date,
'is_overdue' => $nextInstallment->due_date < now()->format('Y-m-d'),
] : null,
@ -1395,7 +1400,7 @@ public function futureTransactions(Request $request)
'data' => $result,
'currency' => $this->primaryCurrency,
'summary' => [
'total_items' => count($result),
'total_transactions' => count($result),
'total_income' => round($totalIncomeConverted, 2),
'total_expense' => round($totalExpenseConverted, 2),
'net_impact' => round($totalIncomeConverted - $totalExpenseConverted, 2),
@ -1660,8 +1665,8 @@ private function getNextRecurrenceDates($recurrence, $startDate, $endDate)
// Calcular la primera fecha dentro del período
$current = $recStart->copy();
// Avanzar hasta estar dentro del período
while ($current->lt($start)) {
// Avanzar hasta estar dentro del período (EXCLUYE startDate para evitar duplicados)
while ($current->lte($start)) {
$current = $this->advanceToNextOccurrence($current, $recurrence);
if ($current->gt($end)) {
return $dates;

View File

@ -0,0 +1,373 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Category;
use App\Models\User;
class CategoriesSeeder extends Seeder
{
/**
* Popula a base de dados com categorias e subcategorias diversificadas
*/
public function run(): void
{
// Obtém o primeiro usuário do sistema
$user = User::first();
if (!$user) {
$this->command->error('Nenhum usuário encontrado! Crie um usuário primeiro.');
return;
}
$this->command->info('Populando categorias para o usuário: ' . $user->email);
// Define as categorias e subcategorias
$categories = [
// DESPESAS
[
'name' => 'Alimentação',
'type' => 'expense',
'color' => '#EF4444',
'icon' => 'bi-egg-fried',
'children' => [
['name' => 'Supermercado', 'color' => '#DC2626', 'icon' => 'bi-cart4'],
['name' => 'Restaurantes', 'color' => '#B91C1C', 'icon' => 'bi-cup-hot'],
['name' => 'Fast Food', 'color' => '#991B1B', 'icon' => 'bi-basket'],
['name' => 'Padaria', 'color' => '#7F1D1D', 'icon' => 'bi-shop'],
['name' => 'Café', 'color' => '#450A0A', 'icon' => 'bi-cup-straw'],
['name' => 'Delivery', 'color' => '#FCA5A5', 'icon' => 'bi-box-seam'],
]
],
[
'name' => 'Transporte',
'type' => 'expense',
'color' => '#3B82F6',
'icon' => 'bi-car-front',
'children' => [
['name' => 'Combustível', 'color' => '#2563EB', 'icon' => 'bi-fuel-pump'],
['name' => 'Estacionamento', 'color' => '#1D4ED8', 'icon' => 'bi-p-square'],
['name' => 'Táxi/Uber', 'color' => '#1E40AF', 'icon' => 'bi-taxi-front'],
['name' => 'Transporte Público', 'color' => '#1E3A8A', 'icon' => 'bi-bus-front'],
['name' => 'Manutenção Veículo', 'color' => '#172554', 'icon' => 'bi-tools'],
['name' => 'Pedágio', 'color' => '#93C5FD', 'icon' => 'bi-coin'],
['name' => 'Seguro Veículo', 'color' => '#60A5FA', 'icon' => 'bi-shield-check'],
]
],
[
'name' => 'Moradia',
'type' => 'expense',
'color' => '#8B5CF6',
'icon' => 'bi-house-door',
'children' => [
['name' => 'Aluguel', 'color' => '#7C3AED', 'icon' => 'bi-key'],
['name' => 'Condomínio', 'color' => '#6D28D9', 'icon' => 'bi-building'],
['name' => 'Luz', 'color' => '#5B21B6', 'icon' => 'bi-lightbulb'],
['name' => 'Água', 'color' => '#4C1D95', 'icon' => 'bi-droplet'],
['name' => 'Gás', 'color' => '#2E1065', 'icon' => 'bi-fire'],
['name' => 'Internet', 'color' => '#C4B5FD', 'icon' => 'bi-wifi'],
['name' => 'Telefone', 'color' => '#A78BFA', 'icon' => 'bi-telephone'],
['name' => 'Reparos', 'color' => '#8B5CF6', 'icon' => 'bi-hammer'],
]
],
[
'name' => 'Saúde',
'type' => 'expense',
'color' => '#10B981',
'icon' => 'bi-heart-pulse',
'children' => [
['name' => 'Farmácia', 'color' => '#059669', 'icon' => 'bi-capsule'],
['name' => 'Médico', 'color' => '#047857', 'icon' => 'bi-hospital'],
['name' => 'Dentista', 'color' => '#065F46', 'icon' => 'bi-activity'],
['name' => 'Exames', 'color' => '#064E3B', 'icon' => 'bi-clipboard2-pulse'],
['name' => 'Plano de Saúde', 'color' => '#6EE7B7', 'icon' => 'bi-bandaid'],
['name' => 'Academia', 'color' => '#34D399', 'icon' => 'bi-bicycle'],
]
],
[
'name' => 'Educação',
'type' => 'expense',
'color' => '#F59E0B',
'icon' => 'bi-mortarboard',
'children' => [
['name' => 'Mensalidade', 'color' => '#D97706', 'icon' => 'bi-bank'],
['name' => 'Livros', 'color' => '#B45309', 'icon' => 'bi-book'],
['name' => 'Material Escolar', 'color' => '#92400E', 'icon' => 'bi-pencil'],
['name' => 'Cursos Online', 'color' => '#78350F', 'icon' => 'bi-laptop'],
['name' => 'Idiomas', 'color' => '#FCD34D', 'icon' => 'bi-translate'],
]
],
[
'name' => 'Lazer',
'type' => 'expense',
'color' => '#EC4899',
'icon' => 'bi-controller',
'children' => [
['name' => 'Cinema', 'color' => '#DB2777', 'icon' => 'bi-film'],
['name' => 'Teatro', 'color' => '#BE185D', 'icon' => 'bi-music-note-beamed'],
['name' => 'Streaming', 'color' => '#9F1239', 'icon' => 'bi-play-btn'],
['name' => 'Viagens', 'color' => '#881337', 'icon' => 'bi-airplane'],
['name' => 'Hobbies', 'color' => '#F9A8D4', 'icon' => 'bi-palette'],
['name' => 'Eventos', 'color' => '#F472B6', 'icon' => 'bi-calendar-event'],
]
],
[
'name' => 'Vestuário',
'type' => 'expense',
'color' => '#06B6D4',
'icon' => 'bi-bag',
'children' => [
['name' => 'Roupas', 'color' => '#0891B2', 'icon' => 'bi-person'],
['name' => 'Calçados', 'color' => '#0E7490', 'icon' => 'bi-foot'],
['name' => 'Acessórios', 'color' => '#155E75', 'icon' => 'bi-watch'],
['name' => 'Óculos', 'color' => '#164E63', 'icon' => 'bi-sunglasses'],
]
],
[
'name' => 'Beleza & Cuidados',
'type' => 'expense',
'color' => '#A855F7',
'icon' => 'bi-scissors',
'children' => [
['name' => 'Cabeleireiro', 'color' => '#9333EA', 'icon' => 'bi-brush'],
['name' => 'Barbeiro', 'color' => '#7E22CE', 'icon' => 'bi-scissors'],
['name' => 'Manicure', 'color' => '#6B21A8', 'icon' => 'bi-hand-index'],
['name' => 'Estética', 'color' => '#581C87', 'icon' => 'bi-stars'],
['name' => 'Cosméticos', 'color' => '#E9D5FF', 'icon' => 'bi-basket'],
]
],
[
'name' => 'Tecnologia',
'type' => 'expense',
'color' => '#6366F1',
'icon' => 'bi-cpu',
'children' => [
['name' => 'Eletrônicos', 'color' => '#4F46E5', 'icon' => 'bi-laptop'],
['name' => 'Software', 'color' => '#4338CA', 'icon' => 'bi-code-slash'],
['name' => 'Smartphone', 'color' => '#3730A3', 'icon' => 'bi-phone'],
['name' => 'Manutenção TI', 'color' => '#312E81', 'icon' => 'bi-tools'],
['name' => 'Cloud/SaaS', 'color' => '#C7D2FE', 'icon' => 'bi-cloud'],
]
],
[
'name' => 'Pets',
'type' => 'expense',
'color' => '#14B8A6',
'icon' => 'bi-paw',
'children' => [
['name' => 'Ração', 'color' => '#0D9488', 'icon' => 'bi-basket'],
['name' => 'Veterinário', 'color' => '#0F766E', 'icon' => 'bi-hospital'],
['name' => 'Pet Shop', 'color' => '#115E59', 'icon' => 'bi-shop'],
['name' => 'Medicamentos', 'color' => '#134E4A', 'icon' => 'bi-capsule'],
]
],
[
'name' => 'Vending',
'type' => 'expense',
'color' => '#FB923C',
'icon' => 'bi-grid-3x3',
'children' => [
['name' => 'Máquinas de Café', 'color' => '#F97316', 'icon' => 'bi-cup-hot'],
['name' => 'Máquinas de Snacks', 'color' => '#EA580C', 'icon' => 'bi-basket3'],
['name' => 'Máquinas de Bebidas', 'color' => '#C2410C', 'icon' => 'bi-cup-straw'],
['name' => 'Manutenção Máquinas', 'color' => '#9A3412', 'icon' => 'bi-gear'],
['name' => 'Reposição Produtos', 'color' => '#7C2D12', 'icon' => 'bi-box-seam'],
['name' => 'Aluguel Máquinas', 'color' => '#FDBA74', 'icon' => 'bi-receipt'],
['name' => 'Logística Vending', 'color' => '#FB923C', 'icon' => 'bi-truck'],
]
],
[
'name' => 'Vaper/Tabaco',
'type' => 'expense',
'color' => '#64748B',
'icon' => 'bi-cloud-fog2',
'children' => [
['name' => 'Vapes/Pods', 'color' => '#475569', 'icon' => 'bi-cloud-fog'],
['name' => 'E-líquidos', 'color' => '#334155', 'icon' => 'bi-droplet'],
['name' => 'Cigarros', 'color' => '#1E293B', 'icon' => 'bi-fire'],
['name' => 'Acessórios Vaping', 'color' => '#0F172A', 'icon' => 'bi-gear'],
['name' => 'Resistências/Coils', 'color' => '#94A3B8', 'icon' => 'bi-cpu'],
['name' => 'Carregadores', 'color' => '#CBD5E1', 'icon' => 'bi-battery-charging'],
]
],
[
'name' => 'Investimentos',
'type' => 'expense',
'color' => '#22C55E',
'icon' => 'bi-graph-up-arrow',
'children' => [
['name' => 'Ações', 'color' => '#16A34A', 'icon' => 'bi-bar-chart'],
['name' => 'Fundos', 'color' => '#15803D', 'icon' => 'bi-piggy-bank'],
['name' => 'Cripto', 'color' => '#166534', 'icon' => 'bi-currency-bitcoin'],
['name' => 'Previdência', 'color' => '#14532D', 'icon' => 'bi-shield'],
]
],
[
'name' => 'Impostos & Taxas',
'type' => 'expense',
'color' => '#DC2626',
'icon' => 'bi-file-earmark-text',
'children' => [
['name' => 'IPTU', 'color' => '#B91C1C', 'icon' => 'bi-house'],
['name' => 'IPVA', 'color' => '#991B1B', 'icon' => 'bi-car-front'],
['name' => 'Imposto de Renda', 'color' => '#7F1D1D', 'icon' => 'bi-file-ruled'],
['name' => 'Taxas Bancárias', 'color' => '#450A0A', 'icon' => 'bi-bank'],
]
],
[
'name' => 'Seguros',
'type' => 'expense',
'color' => '#0EA5E9',
'icon' => 'bi-shield-check',
'children' => [
['name' => 'Seguro de Vida', 'color' => '#0284C7', 'icon' => 'bi-heart'],
['name' => 'Seguro Residencial', 'color' => '#0369A1', 'icon' => 'bi-house-door'],
['name' => 'Seguro Auto', 'color' => '#075985', 'icon' => 'bi-car-front'],
]
],
[
'name' => 'Presentes & Doações',
'type' => 'expense',
'color' => '#F43F5E',
'icon' => 'bi-gift',
'children' => [
['name' => 'Presentes', 'color' => '#E11D48', 'icon' => 'bi-box2-heart'],
['name' => 'Doações', 'color' => '#BE123C', 'icon' => 'bi-heart-fill'],
['name' => 'Caridade', 'color' => '#9F1239', 'icon' => 'bi-people'],
]
],
[
'name' => 'Empréstimos',
'type' => 'expense',
'color' => '#84CC16',
'icon' => 'bi-cash-coin',
'children' => [
['name' => 'Financiamento Imóvel', 'color' => '#65A30D', 'icon' => 'bi-house'],
['name' => 'Financiamento Veículo', 'color' => '#4D7C0F', 'icon' => 'bi-car-front'],
['name' => 'Empréstimo Pessoal', 'color' => '#3F6212', 'icon' => 'bi-person'],
['name' => 'Cartão de Crédito', 'color' => '#365314', 'icon' => 'bi-credit-card'],
]
],
// RECEITAS
[
'name' => 'Salário',
'type' => 'income',
'color' => '#22C55E',
'icon' => 'bi-wallet2',
'children' => [
['name' => 'Salário Fixo', 'color' => '#16A34A', 'icon' => 'bi-cash-stack'],
['name' => 'Horas Extra', 'color' => '#15803D', 'icon' => 'bi-clock'],
['name' => 'Bonificação', 'color' => '#166534', 'icon' => 'bi-star'],
['name' => 'Comissões', 'color' => '#14532D', 'icon' => 'bi-percent'],
]
],
[
'name' => 'Negócios',
'type' => 'income',
'color' => '#3B82F6',
'icon' => 'bi-briefcase',
'children' => [
['name' => 'Vendas', 'color' => '#2563EB', 'icon' => 'bi-cart-check'],
['name' => 'Serviços', 'color' => '#1D4ED8', 'icon' => 'bi-tools'],
['name' => 'Consultoria', 'color' => '#1E40AF', 'icon' => 'bi-person-badge'],
['name' => 'Freelance', 'color' => '#1E3A8A', 'icon' => 'bi-laptop'],
]
],
[
'name' => 'Investimentos',
'type' => 'income',
'color' => '#10B981',
'icon' => 'bi-graph-up',
'children' => [
['name' => 'Dividendos', 'color' => '#059669', 'icon' => 'bi-currency-dollar'],
['name' => 'Juros', 'color' => '#047857', 'icon' => 'bi-percent'],
['name' => 'Lucro Cripto', 'color' => '#065F46', 'icon' => 'bi-currency-bitcoin'],
['name' => 'Aluguel de Imóveis', 'color' => '#064E3B', 'icon' => 'bi-house'],
]
],
[
'name' => 'Receitas Vending',
'type' => 'income',
'color' => '#F59E0B',
'icon' => 'bi-grid-3x3-gap',
'children' => [
['name' => 'Vendas Café', 'color' => '#D97706', 'icon' => 'bi-cup-hot'],
['name' => 'Vendas Snacks', 'color' => '#B45309', 'icon' => 'bi-basket'],
['name' => 'Vendas Bebidas', 'color' => '#92400E', 'icon' => 'bi-cup-straw'],
['name' => 'Vendas Produtos', 'color' => '#78350F', 'icon' => 'bi-box'],
]
],
[
'name' => 'Receitas Vaper/Tabaco',
'type' => 'income',
'color' => '#475569',
'icon' => 'bi-cloud-fog2-fill',
'children' => [
['name' => 'Vendas Vapes', 'color' => '#334155', 'icon' => 'bi-cloud'],
['name' => 'Vendas E-líquidos', 'color' => '#1E293B', 'icon' => 'bi-droplet-fill'],
['name' => 'Vendas Cigarros', 'color' => '#0F172A', 'icon' => 'bi-fire'],
['name' => 'Vendas Acessórios', 'color' => '#64748B', 'icon' => 'bi-gear-fill'],
]
],
[
'name' => 'Outras Receitas',
'type' => 'income',
'color' => '#8B5CF6',
'icon' => 'bi-cash',
'children' => [
['name' => 'Reembolsos', 'color' => '#7C3AED', 'icon' => 'bi-arrow-return-left'],
['name' => 'Presentes Recebidos', 'color' => '#6D28D9', 'icon' => 'bi-gift'],
['name' => 'Prêmios', 'color' => '#5B21B6', 'icon' => 'bi-trophy'],
['name' => 'Pensão', 'color' => '#4C1D95', 'icon' => 'bi-people'],
]
],
];
$order = 0;
foreach ($categories as $categoryData) {
$children = $categoryData['children'] ?? [];
unset($categoryData['children']);
// Cria a categoria pai
$category = Category::create([
'user_id' => $user->id,
'name' => $categoryData['name'],
'type' => $categoryData['type'],
'color' => $categoryData['color'],
'icon' => $categoryData['icon'],
'order' => $order++,
'is_active' => true,
'is_system' => false,
]);
$this->command->info("✓ Criada: {$category->name}");
// Cria as subcategorias
$childOrder = 0;
foreach ($children as $childData) {
$child = Category::create([
'user_id' => $user->id,
'parent_id' => $category->id,
'name' => $childData['name'],
'type' => $category->type,
'color' => $childData['color'],
'icon' => $childData['icon'],
'order' => $childOrder++,
'is_active' => true,
'is_system' => false,
]);
$this->command->info(" └─ {$child->name}");
}
}
$totalCategories = Category::where('user_id', $user->id)->whereNull('parent_id')->count();
$totalSubcategories = Category::where('user_id', $user->id)->whereNotNull('parent_id')->count();
$this->command->info("\n✅ Concluído!");
$this->command->info("Total de categorias: {$totalCategories}");
$this->command->info("Total de subcategorias: {$totalSubcategories}");
}
}