diff --git a/app/Http/Controllers/Netbien/CashCloseController.php b/app/Http/Controllers/Netbien/CashCloseController.php index c6220ec..34fa184 100644 --- a/app/Http/Controllers/Netbien/CashCloseController.php +++ b/app/Http/Controllers/Netbien/CashCloseController.php @@ -199,4 +199,98 @@ public function report(Request $request) 'ventas_detalladas' => $detailedSales, ]); } + + public function exportReport(Request $request) + { + $request->validate([ + 'start_date' => 'nullable|date', + 'end_date' => 'nullable|date|after_or_equal:start_date', + ]); + + $query = CashClose::with('user:id,name')->withCount('sales'); + + if ($request->has('start_date') && $request->has('end_date')) { + $query->whereBetween('close_at', [$request->start_date, $request->end_date]); + } elseif ($request->has('start_date')) { + $query->whereDate('close_at', '>=', $request->start_date); + } elseif ($request->has('end_date')) { + $query->whereDate('close_at', '<=', $request->end_date); + } else { + $query->closed()->orderBy('id', 'desc')->limit(1); + } + + $cashCloses = $query->orderBy('id', 'desc')->get(); + + if ($cashCloses->isEmpty()) { + return ApiResponse::NOT_FOUND->response([ + 'message' => 'No se encontraron cortes de caja en el rango de fechas especificado.', + ]); + } + + $cashCloseIds = $cashCloses->pluck('id')->toArray(); + + // Obtener ventas detalladas + $detailedSales = SaleItem::whereHas('sale', function ($query) use ($cashCloseIds) { + $query->whereIn('cash_close_id', $cashCloseIds); + }) + ->with([ + 'sale.client:id,name,paternal,maternal', + 'sale:id,client_id,payment_method', + 'simCard:id,iccid,msisdn', + 'package:id,name,price' + ]) + ->orderBy('id', 'asc') + ->get(); + + // Calcular totales + $totalIncome = $cashCloses->sum('income'); + $totalExit = $cashCloses->sum('exit'); + $totalCash = $cashCloses->sum('income_cash'); + $totalCard = $cashCloses->sum('income_card'); + $totalTransfer = $cashCloses->sum('income_transfer'); + + // Crear el CSV + $filename = 'reporte_corte_caja_' . date('Y-m-d_His') . '.csv'; + + $headers = [ + 'Content-Type' => 'text/csv; charset=UTF-8', + 'Content-Disposition' => 'attachment; filename="' . $filename . '"', + ]; + + $callback = function () use ($cashCloses, $detailedSales, $totalIncome, $totalExit, $totalCash, $totalCard, $totalTransfer) { + $file = fopen('php://output', 'w'); + + fprintf($file, chr(0xEF) . chr(0xBB) . chr(0xBF)); + + // RESUMEN FINANCIERO + fputcsv($file, ['RESUMEN FINANCIERO', '']); + fputcsv($file, ['Periodo Inicio', $cashCloses->last()?->opened_at]); + fputcsv($file, ['Periodo Fin', $cashCloses->first()?->closed_at]); + fputcsv($file, ['Total Ventas', number_format($totalIncome, 2)]); + fputcsv($file, ['Efectivo', number_format($totalCash, 2)]); + fputcsv($file, ['Tarjeta', number_format($totalCard, 2)]); + fputcsv($file, ['Transferencia', number_format($totalTransfer, 2)]); + fputcsv($file, ['Egresos', number_format($totalExit, 2)]); + fputcsv($file, []); + + // VENTAS DETALLADAS + fputcsv($file, ['VENTAS DETALLADAS']); + fputcsv($file, ['Nombre Comprador', 'ID SIM', 'Número Asignado', 'Paquete', 'Costo', 'Medio de Pago']); + + foreach ($detailedSales as $item) { + fputcsv($file, [ + $item->sale->client->full_name, + "'" . $item->simCard->iccid . "'", + "'" . $item->simCard->msisdn . "'", + $item->package->name, + number_format($item->package->price, 2), + ucfirst($item->sale->payment_method) + ]); + } + + fclose($file); + }; + + return response()->stream($callback, 200, $headers); + } } diff --git a/routes/api.php b/routes/api.php index 51fd845..880187a 100644 --- a/routes/api.php +++ b/routes/api.php @@ -36,6 +36,7 @@ Route::get('cash-closes', [CashCloseController::class, 'index']); Route::put('cash-closes/close', [CashCloseController::class, 'CloseCashClose']); Route::get('cash-closes/report', [CashCloseController::class, 'report']); + Route::get('cash-closes/export', [CashCloseController::class, 'exportReport']); }); /** Rutas públicas */