From e679bcaedfbd400cd212207f53c205fb613ec431 Mon Sep 17 00:00:00 2001 From: Juan Felipe Zapata Moreno Date: Mon, 10 Nov 2025 10:09:59 -0600 Subject: [PATCH] FIX: Reporte de corte de caja por rango de fecha --- .../Netbien/CashCloseController.php | 90 ++++++++++++++----- routes/api.php | 2 +- 2 files changed, 68 insertions(+), 24 deletions(-) diff --git a/app/Http/Controllers/Netbien/CashCloseController.php b/app/Http/Controllers/Netbien/CashCloseController.php index a899e57..c6220ec 100644 --- a/app/Http/Controllers/Netbien/CashCloseController.php +++ b/app/Http/Controllers/Netbien/CashCloseController.php @@ -9,6 +9,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Notsoweb\ApiResponse\Enums\ApiResponse; +use phpseclib3\Crypt\RC2; /** * @@ -38,21 +39,21 @@ public function index(Request $request) public function closeCashClose(Request $request) { - $request ->validate([ - 'exit' => 'sometimes|numeric|min:0', - ]); + $request->validate([ + 'exit' => 'sometimes|numeric|min:0', + ]); - $cashClose = CashClose::open()->first(); + $cashClose = CashClose::open()->first(); - if(!$cashClose) { - return ApiResponse::NOT_FOUND->response([ - 'message' => 'No hay un corte de caja abierto para cerrar.', - ]); - } + if (!$cashClose) { + return ApiResponse::NOT_FOUND->response([ + 'message' => 'No hay un corte de caja abierto para cerrar.', + ]); + } - $totalSales = Sale::where('cash_close_id', $cashClose->id)->sum('total_amount'); + $totalSales = Sale::where('cash_close_id', $cashClose->id)->sum('total_amount'); - $paymentMethods = Sale::where('cash_close_id', $cashClose->id) + $paymentMethods = Sale::where('cash_close_id', $cashClose->id) ->select('payment_method', DB::raw('SUM(total_amount) as total')) ->groupBy('payment_method') ->pluck('total', 'payment_method'); @@ -92,21 +93,45 @@ public function closeCashClose(Request $request) ]); } - public function report($id) + public function report(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_date', [$request->start_date, $request->end_date]); + } elseif ($request->has('start_date')) { + $query->whereDate('close_date', '>=', $request->start_date); + } elseif ($request->has('end_date')) { + $query->whereDate('close_date', '<=', $request->end_date); + } else { + $query->closed()->orderBy('id', 'desc')->limit(1); + } + // Información del corte de caja - $cashClose = CashClose::with('user:id,name') - ->withCount('sales') - ->findOrFail($id); + $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(); // Estadísticas por paquete (Total de Paquetes Vendidos por Tipo) $packageStats = DB::table('sale_items') ->join('sales', 'sale_items.sale_id', '=', 'sales.id') ->join('packages', 'sale_items.package_id', '=', 'packages.id') - ->where('sales.cash_close_id', $id) + ->whereIn('sales.cash_close_id', $cashCloseIds) ->select( 'packages.name as paquete', - DB::raw('COUNT(*) as total_vendidos') + DB::raw('COUNT(*) as total_vendidos'), + DB::raw('SUM(packages.price) as total_ingresos') ) ->groupBy('packages.id', 'packages.name') ->get(); @@ -115,7 +140,7 @@ public function report($id) $durationStats = DB::table('sale_items') ->join('sales', 'sale_items.sale_id', '=', 'sales.id') ->join('packages', 'sale_items.package_id', '=', 'packages.id') - ->where('sales.cash_close_id', $id) + ->whereIn('sales.cash_close_id', $cashCloseIds) ->select( 'packages.period as duracion_dias', DB::raw('COUNT(DISTINCT sales.id) as total_ventas') @@ -125,9 +150,9 @@ public function report($id) ->get(); // Reporte detallado de ventas - $detailedSales = SaleItem::whereHas('sale', function($query) use ($id) { - $query->where('cash_close_id', $id); - }) + $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', @@ -136,7 +161,7 @@ public function report($id) ]) ->orderBy('id', 'asc') ->paginate(config('app.pagination')) - ->through(function($item) { + ->through(function ($item) { return [ 'nombre_comprador' => $item->sale->client->full_name, 'id_sim' => $item->simCard->iccid, @@ -147,9 +172,28 @@ public function report($id) ]; }); + $totalIncome = $cashCloses->sum('income'); + $totalExit = $cashCloses->sum('exit'); + $totalCash = $cashCloses->sum('income_cash'); + $totalCard = $cashCloses->sum('income_card'); + $totalTransfer = $cashCloses->sum('income_transfer'); + $balanceFinal = $cashCloses->sum('initial_balance') + $totalIncome - $totalExit; + return ApiResponse::OK->response([ - 'cash_close' => $cashClose, + 'cash_closes' => $cashCloses, + 'periodo' => [ + 'inicio' => $cashCloses->last()?->opened_at, + 'fin' => $cashCloses->first()?->closed_at, + ], + 'resumen_financiero' => [ + 'total_ventas' => $totalIncome, + 'efectivo' => $totalCash, + 'tarjeta' => $totalCard, + 'transferencia' => $totalTransfer, + 'egresos' => $totalExit, + 'balance_final' => $balanceFinal, + ], 'ventas_paquete' => $packageStats, 'ventas_duracion' => $durationStats, 'ventas_detalladas' => $detailedSales, diff --git a/routes/api.php b/routes/api.php index 5f3e2c9..51fd845 100644 --- a/routes/api.php +++ b/routes/api.php @@ -35,7 +35,7 @@ Route::get('cash-closes', [CashCloseController::class, 'index']); Route::put('cash-closes/close', [CashCloseController::class, 'CloseCashClose']); - Route::get('cash-closes/{id}/report', [CashCloseController::class, 'report']); + Route::get('cash-closes/report', [CashCloseController::class, 'report']); }); /** Rutas públicas */