pagoRepo->obtenerPorPedidoId($pedidoId); $pagoYaRegistrado = false; if ($pagoExistente && $pagoExistente->getEstado() === 'COMPLETED') { \Illuminate\Support\Facades\Log::warning("⚠️ [UC TARJETA] Pago ya registrado para pedido $pedidoId. Activando modo Auto-Recuperación."); $pagoYaRegistrado = true; } $pedido = $this->pedidoRepo->obtenerPorId($pedidoId); if (!$pedido) { throw new Exception("Pedido no encontrado"); } // 2. Marcar pedido como pagado (incluyendo Pago Adelantado) // El estado PAGADO permite que el cajero vea el botón azul "FACTURAR" $pedido->estado = \App\Modules\Orders\Domain\ValueObjects\EstadoPedido::pagado(); $pedido->fechaServido = new \DateTimeImmutable(); $this->pedidoRepo->actualizar($pedido); $mesaPagoAdelantado = false; if (!empty($pedido->mesaId)) { try { $m = $this->mesaRepo->obtenerPorId($pedido->mesaId); $mesaPagoAdelantado = $m && $m->pagoAdelantado; } catch (\Exception $e) {} } // Buscar y cerrar pedidos hermanos asociados a la misma mesa if (!empty($pedido->mesaId) && !$mesaPagoAdelantado) { $pedidosDeLaMesa = $this->pedidoRepo->obtenerPorMesaYEstados($pedido->mesaId, [ 'PENDIENTE', 'EN_PREPARACION', 'LISTO', 'ENTREGADO', 'POR_CONFIRMAR', 'POR_REVISAR' ]); foreach ($pedidosDeLaMesa as $otroPedido) { if (!$otroPedido->estaCompletado() && !$otroPedido->estaCancelado() && !$otroPedido->estado->esCerrado() && !$otroPedido->estado->esPagado()) { $otroPedido->estado = \App\Modules\Orders\Domain\ValueObjects\EstadoPedido::pagado(); $otroPedido->fechaServido = $pedido->fechaServido; $this->pedidoRepo->actualizar($otroPedido); } } } // Liberar la Mesa físicamente if ($pedido->mesaId) { try { $mesa = $this->mesaRepo->obtenerPorId($pedido->mesaId); if ($mesa) { if (!$mesa->pagoAdelantado) { $mesa->liberar(); $this->mesaRepo->guardar($mesa); // Asegurar estado LIBRE en la BD legacy/recursos $this->mesaRepo->actualizarEstado($pedido->mesaId, 'LIBRE'); // 🧹 Limpiar pedidos activos de la mesa liberada try { app(\App\Modules\Orders\Domain\Repositories\PedidoRepositoryInterface::class)->limpiarPedidosAlLiberarMesa($pedido->mesaId); } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error("❌ Error llamando a limpiarPedidosAlLiberarMesa: " . $e->getMessage()); } } } } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error("❌ ERROR AL LIBERAR MESA POS: " . $e->getMessage()); } } // 3. Registrar el Pago Financieramente if (!$pagoYaRegistrado) { $pago = new Pago( id: (string) Str::uuid(), pedidoId: $pedidoId, monto: $monto, moneda: 'PEN', estado: 'COMPLETED', metodoPago: $metodo, montoPropina: $montoPropina, meseroId: $meseroId ?: $pedido->usuarioId, // [FIX] Fallback to original waiter preferenciaId: $pedidoId, descripcion: "Pago con $metodo - Mesa {$pedido->mesaNombre}", creadoAt: new \DateTimeImmutable() ); $this->pagoRepo->guardar($pago); } // 4. Notificar al cajero en tiempo real if (!$pagoYaRegistrado) { try { $notificationData = [ 'pedido_id' => $pedidoId, 'mesa_id' => $pedido->mesaId, 'mesa_nombre' => $pedido->mesaNombre, 'sucursal_id' => $pedido->sucursalId, 'usuario_id' => $pedido->usuarioId, // Mesero que lo registró 'total' => $monto, 'monto_propina' => $montoPropina, 'metodo' => $metodo, ]; $notificationType = ($metodo === 'YAPE_POS') ? 'pago_yape_pos' : 'pago_tarjeta_pos'; \App\Jobs\NotifyPedidoJob::dispatch($notificationData, $notificationType); \Illuminate\Support\Facades\Log::info("🔌 CHISMOSO: NotifyPedidoJob ($notificationType) despachado correctamente para Mesa: {$pedido->mesaNombre}"); } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error("❌ CHISMOSO ERROR al despachar NotifyPedidoJob POS: " . $e->getMessage()); } // 5. Registrar Ingreso en Caja (Monto total incluye propina para el arqueo de POS pero se separa en reporte) try { $cajaActiva = $this->cajaRepo->findBySucursalAndEstado($pedido->sucursalId, 'OPEN'); if ($cajaActiva) { DB::table('Pagos_Ingresos')->insert([ 'id_ingreso' => (string) Str::uuid(), 'caja_diaria_id' => $cajaActiva->getId(), 'orden_id' => $pedidoId, 'monto' => $monto + $montoPropina, 'metodo_pago' => $metodo, 'SysStartTime' => now() ]); } } catch (\Exception $e) { // Log error but don't fail the transaction } } return [ 'pedido_id' => $pedidoId, 'estado' => 'pagado', 'monto_consumo' => $monto, 'monto_propina' => $montoPropina, 'total_procesado' => $monto + $montoPropina, 'mesero_id' => $meseroId, 'mensaje' => 'Pago con tarjeta/Yape registrado exitosamente' ]; } }