- Agregado grafico de torta de "Ingresos por categoria" para mayor utiidad de los reportes.
This commit is contained in:
Bryam105
2026-06-12 09:09:19 -03:00
parent 2454ee3a23
commit cf130fe7cb
2 changed files with 84 additions and 7 deletions
+26
View File
@@ -23,6 +23,31 @@ class ReportController extends Controller
->groupBy('expense_category')
->get();
// 2.5 Ingresos por Categoría (Para Pie Chart)
$rawEarningsByCategory = \App\Models\SaleDetail::join('products', 'sale_details.product_id', '=', 'products.id')
->select('products.type', DB::raw('SUM(sale_details.quantity * sale_details.price) as total_earnings'))
->groupBy('products.type')
->get();
$categoryTranslations = [
'bike' => 'Bicicletas',
'clothing' => 'Indumentaria',
'accessory' => 'Accesorios',
'spare' => 'Repuestos',
'children' => 'Niños',
'rollers' => 'Rollers',
'skate' => 'Skates',
'other' => 'Otros'
];
$earningsByCategory = $rawEarningsByCategory->map(function($item) use ($categoryTranslations) {
$type = $item->type;
return [
'category' => $categoryTranslations[$type] ?? ucfirst($type),
'total' => $item->total_earnings
];
});
// 3. Ingresos y Egresos por Mes (Últimos 6 meses)
$months = [];
$monthlyIncomeData = [];
@@ -81,6 +106,7 @@ class ReportController extends Controller
'totalOutcome',
'balance',
'expensesByCategory',
'earningsByCategory',
'months',
'monthlyIncomeData',
'monthlyOutcomeData',
+57 -6
View File
@@ -50,19 +50,27 @@
</div>
</div>
<!-- Gráficos -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Gráfico de Líneas/Barras -->
<div class="bg-gray-200 dark:bg-panel-bg border border-neutral-400 dark:border-neutral-800 rounded-xl p-6 shadow-lg">
<!-- Gráfico de Evolución -->
<div class="mb-6 bg-gray-200 dark:bg-panel-bg border border-neutral-400 dark:border-neutral-800 rounded-xl p-6 shadow-lg">
<h3 class="text-lg font-bold text-neutral-900 dark:text-white mb-4">Evolución de Ingresos y Egresos (Últimos 6 meses)</h3>
<div class="relative h-72 w-full">
<canvas id="balanceChart"></canvas>
</div>
</div>
<!-- Gráfico de Torta -->
<!-- Gráficos de Torta (Distribución) -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Gráfico de Torta Ingresos -->
<div class="bg-gray-200 dark:bg-panel-bg border border-neutral-400 dark:border-neutral-800 rounded-xl p-6 shadow-lg">
<h3 class="text-lg font-bold text-neutral-900 dark:text-white mb-4">Distribución de Gastos por Categoría</h3>
<h3 class="text-lg font-bold text-neutral-900 dark:text-white mb-4">Ingresos por Categoría</h3>
<div class="relative h-72 w-full flex justify-center">
<canvas id="earningsChart"></canvas>
</div>
</div>
<!-- Gráfico de Torta Gastos -->
<div class="bg-gray-200 dark:bg-panel-bg border border-neutral-400 dark:border-neutral-800 rounded-xl p-6 shadow-lg">
<h3 class="text-lg font-bold text-neutral-900 dark:text-white mb-4">Gastos por Categoría</h3>
<div class="relative h-72 w-full flex justify-center">
<canvas id="expensesChart"></canvas>
</div>
@@ -211,6 +219,49 @@
}
});
// --- GRÁFICO DE INGRESOS POR CATEGORÍA (Torta) ---
const ctxEarnings = document.getElementById('earningsChart').getContext('2d');
const rawEarnings = @json($earningsByCategory);
const earnLabels = rawEarnings.map(item => item.category);
const earnData = rawEarnings.map(item => item.total);
// Paleta de colores distintiva (verdes/limas/turquesas)
const earnColors = [
'#84cc16', // neon-lime / lime-500
'#14b8a6', // teal-500
'#06b6d4', // cyan-500
'#6366f1', // indigo-500
'#10b981', // emerald-500
'#eab308', // yellow-500
'#f97316', // orange-500
'#8b5cf6' // violet-500
];
new Chart(ctxEarnings, {
type: 'doughnut',
data: {
labels: earnLabels,
datasets: [{
data: earnData,
backgroundColor: earnColors,
borderWidth: 2,
borderColor: isDark ? '#1f2937' : '#ffffff'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right',
labels: { color: textColor, padding: 20 }
}
},
cutout: '60%'
}
});
// --- GRÁFICO DE TOP PRODUCTOS ---
const ctxTopProducts = document.getElementById('topProductsChart').getContext('2d');
const rawTopProducts = @json($topProducts);