busquedaParaServicio(); ob_start(); require __DIR__ . '/../views/servicios/crearServicioView.php'; return ob_get_clean(); } // GUARDADO INICIAL DEL SERVICIO case 'guardar_servicio': // Cliente y vendedor $cliente = $_SESSION['servicio']['cliente'] ?? null; $vendedor = $_SESSION['user'] ?? ''; // Tomo los datos del form $descripcionEquipo = trim($_POST['descripcion_equipo']) ?? ''; $contraseniaEquipo = trim($_POST['contrasenia_equipo']) ?? ''; $cuenta = trim($_POST['cuenta']) ?? ''; $contraseniaCuenta = trim($_POST['contrasenia_cuenta']) ?? ''; $descripcionProblema = trim($_POST['descripcion_problema']) ?? ''; $observacion = trim($_POST['observacion']) ?? ''; if (!$cliente) { $_SESSION['flash_error'] = "Debe seleccionar el cliente."; header("Location: index.php?opt=crear_servicio"); exit; } // Validaciones $errores = []; if ($descripcionEquipo === '') { $errores[] = "La descripción del equipo es obligatoria."; } if ($descripcionProblema === '') { $errores[] = "Debe describir el problema."; } // Validacion de longitud if (strlen($descripcionEquipo) > 100) { $errores[] = "La descripción del equipo es demasiado larga."; } if (strlen($descripcionProblema) > 2000) { $errores[] = "La descripción del problema es demasiada larga."; } if (strlen($contraseniaEquipo) > 100) { $errores[] = "Contraseña demasiado larga."; } if (strlen($observacion) > 500) { $errores[] = "La descripción de la observación es demasiada larga."; } if (strlen($cuenta) > 100) { $errores[] = "Cuenta demasiado larga."; } if (strlen($contraseniaCuenta) > 100) { $errores[] = "Contraseña de cuenta demasiado larga."; } // Otras validaciones if (!empty($cuenta) && !filter_var($cuenta, FILTER_VALIDATE_EMAIL)) { $errores[] = "El email de la cuenta no es válido."; } if ($contraseniaEquipo !== '' && $descripcionEquipo === '') { $errores[] = "Debe indicar el equipo si ingresa contraseña."; } if ($contraseniaCuenta !== '' && $cuenta === '') { $errores[] = "Debe indicar la cuenta si ingresa contraseña."; } if (!empty($errores)) { $_SESSION['flash_error'] = implode('
', $errores); header("Location:index.php?opt=crear_servicio"); exit; } // Guardado de datos en array $datosServicio = [ 'descripcion_equipo' => $descripcionEquipo, 'cuenta' => $cuenta, 'descripcion_problema' => $descripcionProblema, 'observacion' => $observacion ]; // Encriptamos las contraseñas if ($contraseniaEquipo !== '') { $datosServicio['contrasenia_equipo'] = encryptData($contraseniaEquipo); } if ($contraseniaCuenta !== '') { $datosServicio['contrasenia_cuenta'] = encryptData($contraseniaCuenta); } // Llamado a modelo de servicio require_once __DIR__ . '/../models/servicioModel.php'; $serviciomodel = new servicioModel(); // NÚMERO DE SERVICIO (OBTENIDO MEDIANTE SECUENCIA PREVIEW) if (isset($_SESSION['servicio_numero'])) { $numero = $_SESSION['servicio_numero']; } else { $numero = $serviciomodel->getNumeroServicioPreview(); $_SESSION['servicio_numero'] = $numero; } if ($serviciomodel->guardarServicio($numero, $datosServicio, $cliente, $vendedor)) { $_SESSION['flash_success'] = "Servicio guardado correctamente."; unset($_SESSION['servicio']['cliente']); } else { $_SESSION['flash_error'] = "Hubo un error al crear el servicio."; } header("Location:index.php?opt=crear_servicio"); exit; // SELECCIONAR CLIENTE PARA EL SERVICIO case 'seleccionar_cliente_servicio': require_once __DIR__ . '/../models/clienteModel.php'; $clientemodel = new clienteModel(); // Se muestra la vista de selección de cliente if ($_SERVER['REQUEST_METHOD'] === 'GET') { $clientes = $clientemodel->listarClientes(); ob_start(); require __DIR__ . '/../views/servicios/seleccionarClienteView.php'; return ob_get_clean(); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $idCliente = (int) ($_POST['id_cliente'] ?? 0); if ($idCliente <= 0) { $_SESSION['flash_error'] = "No se seleccionó ningún cliente."; header("Location: index.php?opt=seleccionar_cliente"); exit; } $cliente = $clientemodel->obtenerPorId($idCliente); if (!$cliente) { $_SESSION['flash_error'] = "Cliente inválido."; header("Location: index.php?opt=seleccionar_cliente"); exit; } $_SESSION['servicio']['cliente'] = [ 'id' => $cliente['id'], 'nombre' => $cliente['nombre'], 'apellido' => $cliente['apellido'], 'telefono' => $cliente['telefono'], 'email' => $cliente['email'] ]; $_SESSION['flash_success'] = "Cliente agregado correctamente."; header("Location: index.php?opt=crear_servicio"); exit; } // ELIMINAR CLIENTE YA SELECCIONADO case 'eliminar_cliente_servicio': if (isset($_SESSION['servicio']['cliente'])) { unset($_SESSION['servicio']['cliente']); $_SESSION['flash_success'] = "Cliente eliminado correctamente."; } else { $_SESSION['flash_error'] = "No había cliente seleccionado."; } header("Location: index.php?opt=crear_servicio"); exit; // GENERACION DE COMRPOBANTE DE SERVCIO PDF MEDIANTE USO DE LIBRERIA DOMPDF case 'generar_servicio_pdf': // Requiero datos de empresa y configuración require __DIR__ . '/../models/configuracionModel.php'; $configuracionmodel = new configuracionModel(); $datosEmpresa = $configuracionmodel->obtenerConfiguracion(); $mapCondIVA = [ 'consumidor_final' => 'Consumidor Final', 'responsable_inscripto' => 'Responsable Inscripto', 'monotributo' => 'Monotributo', ]; $datosEmpresa['cond_iva'] = $mapCondIVA[$datosEmpresa['cond_iva']]; $cliente = $_SESSION['servicio']['cliente'] ?? null; $vendedor = $_SESSION['user'] ?? null; // DATOS FORM $descripcionEquipo = trim($_POST['descripcion_equipo']) ?? ''; $contraseniaEquipo = trim($_POST['contrasenia_equipo']) ?? ''; $cuenta = trim($_POST['cuenta']) ?? ''; $contraseniaCuenta = trim($_POST['contrasenia_cuenta']) ?? ''; $descripcionProblema = trim($_POST['descripcion_problema']) ?? ''; $observacion = trim($_POST['observacion']) ?? ''; // VALIDACIONES $errores = []; if ($descripcionEquipo === '') { $errores[] = "La descripción del equipo es obligatoria."; } if ($descripcionProblema === '') { $errores[] = "Debe describir el problema."; } // Validacion de longitud if (strlen($descripcionEquipo) > 100) { $errores[] = "La descripción del equipo es demasiado larga."; } if (strlen($descripcionProblema) > 2000) { $errores[] = "La descripción del problema es demasiada larga."; } if (strlen($contraseniaEquipo) > 100) { $errores[] = "Contraseña demasiado larga."; } if (strlen($observacion) > 500) { $errores[] = "La descripción de la observación es demasiada larga."; } if (strlen($cuenta) > 100) { $errores[] = "Cuenta demasiado larga."; } if (strlen($contraseniaCuenta) > 100) { $errores[] = "Contraseña de cuenta demasiado larga."; } // Otras validaciones if (!empty($cuenta) && !filter_var($cuenta, FILTER_VALIDATE_EMAIL)) { $errores[] = "El email de la cuenta no es válido."; } if ($contraseniaEquipo !== '' && $descripcionEquipo === '') { $errores[] = "Debe indicar el equipo si ingresa contraseña."; } if ($contraseniaCuenta !== '' && $cuenta === '') { $errores[] = "Debe indicar la cuenta si ingresa contraseña."; } if (!empty($errores)) { $_SESSION['flash_error'] = implode('
', $errores); header("Location:index.php?opt=crear_servicio"); exit; } // Guardado de datos en array $datosServicio = [ 'descripcion_equipo' => $descripcionEquipo, 'contrasenia_equipo' => $contraseniaEquipo, 'cuenta' => $cuenta, 'contrasenia_cuenta' => $contraseniaCuenta, 'descripcion_problema' => $descripcionProblema, 'observacion' => $observacion ]; // NÚMERO DE SERVICIO (OBTENIDO MEDIANTE SECUENCIA PREVIEW) require_once __DIR__ . '/../models/servicioModel.php'; $serviciomodel = new servicioModel(); $numero = $serviciomodel->getNumeroServicioPreview(); $_SESSION['servicio_numero'] = $numero; $numeroServicio = '0001-' . str_pad($numero, 8, '0', STR_PAD_LEFT); // RENDER PDF ob_start(); require __DIR__ . '/../pdf/servicios/servicioPDF.php'; $html = ob_get_clean(); $cssPath = '/var/www/html/css/stylesPDF.css'; $css = file_get_contents($cssPath); // Configuración de opciones $options = new Options(); $options->set('isRemoteEnabled', true); // Permite cargar recursos externos (CSS, imágenes, etc.) $options->set('chroot', '/var/www/html'); // Define directorios base para recursos locales $options->set('defaultFont', 'DejaVu Sans'); // Creación de instancia Dompdf con las opciones seteadas $dompdf = new Dompdf($options); // Cargar el HTML que se va a convertir en PDF $dompdf->loadHtml(" $html "); $dompdf->setPaper('A4', 'portrait'); // Define el tamanio de hoja y la orientación $dompdf->render(); // Renderiza el PDF (procesa el HTML) // Enviar el PDF al browser $dompdf->stream( 'Servicio N° ' . $numeroServicio . '.pdf', ['Attachment' => true] // false = se muestra en el navegador | true = descarga directa ); exit; // OBTENER LISTADO DE SERVICIOS case 'listar_servicios': // Requiero el modelo de servicio require_once __DIR__ . '/../models/servicioModel.php'; $serviciomodel = new servicioModel(); $anioActual = date('Y'); $anioSeleccionado = $_GET['anio'] ?? $anioActual; $servicios = $serviciomodel->listarServicios($anioSeleccionado); foreach ($servicios as $i => $s) { // Saneamiento de fecha (para poder ordenar correctamente el campo con dataTables) if (!empty($s['fecha_registro'])) { $dt = new DateTime($s['fecha_registro']); // Para ordenar $servicios[$i]['fecha_registro'] = $dt->format('Y-m-d'); // Para mostrar $servicios[$i]['fecha_formateada'] = $dt->format('d/m/Y'); } else { $servicios[$i]['fecha_registro'] = '-'; $servicios[$i]['fecha_formateada'] = '-'; } if (!empty($s['fecha_terminado'])) { $dt = new DateTime($s['fecha_terminado']); // Para ordenar $servicios[$i]['fecha_terminado'] = $dt->format('Y-m-d'); // Para mostrar $servicios[$i]['fecha_formateada_term'] = $dt->format('d/m/Y'); } else { $servicios[$i]['fecha_terminado'] = '-'; $servicios[$i]['fecha_formateada_term'] = '-'; } // Saneamiento de tipo de pago $servicios[$i]['estado'] = ucwords($servicios[$i]['estado']); } ob_start(); require __DIR__ . '/../views/servicios/listaServiciosView.php'; return ob_get_clean(); // RESETEAR DATOS DE SERVICIO (al querer actualizar un servicio) (básicamente limpia todo para que los campos del form y la caja estén vacíos) case 'resetear_datos_servicio': if ($_SERVER['REQUEST_METHOD'] === 'GET') { // Verifico si es admin if (!$esAdmin) { header("Location: index.php?opt=inicio_operador"); exit; } $idServicio = (int) ($_GET['id'] ?? 0); if ($idServicio <= 0) { $_SESSION['flash_error'] = 'Datos inválidos.'; header('Location: index.php?opt=listar_servicios'); exit; } // Se resetean los campos $manoObra = 0; $detalleRealizado = ''; $total = 0; $_SESSION['servicio']['mano_obra'] = $manoObra; $_SESSION['servicio']['detalle_realizado'] = $detalleRealizado; require_once __DIR__ . '/../models/cajaModel.php'; $cajamodel = new cajaModel(); // Se vacia la caja $cajamodel->vaciarCajaServicio(); $insumos = $cajamodel->listarInsumos(); ob_start(); require __DIR__ . '/../views/servicios/actualizarServicioView.php'; return ob_get_clean(); } // ACTUALIZACIÓN DEL SERVICIO case 'actualizar_servicio': // Verifico si es admin if (!$esAdmin) { header("Location: index.php?opt=inicio_operador"); exit; } require_once __DIR__ . '/../models/servicioModel.php'; $serviciomodel = new servicioModel(); if ($_SERVER['REQUEST_METHOD'] === 'GET') { $idServicio = (int) ($_GET['id'] ?? 0); if ($idServicio <= 0) { $_SESSION['flash_error'] = 'Datos inválidos.'; header('Location: index.php?opt=listar_servicios'); exit; } // Validamos si el servicio se encuentra en estado 'pendiente' if (!($serviciomodel->getEstadoServicio($idServicio))) { $_SESSION['flash_error'] = "El servicio no se encuentra en el estado correspondiente."; header("Location: index.php?opt=listar_servicios"); exit; } $manoObra = isset($_SESSION['servicio']['mano_obra']) ? (float) $_SESSION['servicio']['mano_obra'] : 0; $detalleRealizado = isset($_SESSION['servicio']['detalle_realizado']) ? trim($_SESSION['servicio']['detalle_realizado']) : ''; // Requiero modelo de caja require_once __DIR__ . '/../models/cajaModel.php'; $cajamodel = new cajaModel(); $insumos = $cajamodel->listarInsumos(); $total = $cajamodel->calcularPrecioTotalServicio() ?? 0; if (isset($_SESSION['servicio']['mano_obra'])) { $total = $total + $_SESSION['servicio']['mano_obra']; } ob_start(); require __DIR__ . '/../views/servicios/actualizarServicioView.php'; return ob_get_clean(); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $idServicio = (int) ($_GET['id'] ?? 0); $detalleRealizado = trim($_POST['detalle_realizado'] ?? ''); $manoObra = (float) ($_POST['mano_obra'] ?? 0); // VALIDACIONES $errores = []; if ($idServicio <= 0 || $manoObra < 0) { $_SESSION['flash_error'] = 'Datos inválidos.'; header('Location: index.php?opt=actualizar_servicio&id=' . $idServicio); exit; } if ($detalleRealizado === '') { $errores[] = "El detalle es obligatorio."; } if (strlen($detalleRealizado) > 2000) { $errores[] = "El detalle es demasiado largo."; } if (!empty($errores)) { $_SESSION['flash_error'] = implode('
', $errores); header("Location:index.php?opt=actualizar_servicio&id=" . $idServicio); exit; } // Requiero modelo de caja require_once __DIR__ . '/../models/cajaModel.php'; $cajamodel = new cajaModel(); $insumos = $cajamodel->listarInsumos(); $total = $cajamodel->calcularPrecioTotalServicio(); $totalFinal = $total + $manoObra; if ($totalFinal < 0) { $_SESSION['flash_error'] = 'Total inválido.'; header('Location: index.php?opt=actualizar_servicio&id=' . $idServicio); exit; } $datosServicio = [ 'id_servicio' => $idServicio, 'detalle_realizado' => $detalleRealizado, 'mano_obra' => $manoObra, 'total_final' => $totalFinal ]; // REQUERIMOS EL MODELO SERVICIO Y EL HELPER DEL MAIL require_once __DIR__ . '/../models/servicioModel.php'; require_once __DIR__ . '/../helpers/email_actualizar.php'; $serviciomodel = new servicioModel(); if ($serviciomodel->actualizarServicio($datosServicio, $insumos)) { $success = []; $success[] = "Servicio actualizado correctamente."; unset($_SESSION['servicio']['mano_obra']); unset($_SESSION['servicio']['detalle_realizado']); $cajamodel->vaciarCajaServicio(); // OBTENEMOS DATOS DEL SERVICIO (SERVICIO, INSUMO UTILIZADOS Y CLIENTE) $servicio = $serviciomodel->getDetalleServicio($idServicio); $insumos = $serviciomodel->getDetalleInsumos($idServicio); $cliente = $serviciomodel->getClienteServicio($idServicio); // LLAMO MÉTODO PARA ENVÍO DEL EMAIL $resultadoEnvioMail = enviarMailServicioFinalizado($servicio, $insumos, $cliente); // OBTENGO DATO DE CONFIGURACIÓN PARA DECIDIR QUE MENSAJE MOSTRAR $configuracionmodel = new configuracionModel(); $datosConfig = $configuracionmodel->obtenerDatosEnvioMail(); if (((int) $datosConfig['mail_automatico'] === 1) && $resultadoEnvioMail) { $success[] = "Email automático enviado correctamente."; } if (!$resultadoEnvioMail) { $success[] = "No fué posible enviar el email automático, por favor verifique manualmente."; } $_SESSION['flash_success'] = implode('
', $success); } else { $_SESSION['flash_error'] = $serviciomodel->getError() ?? 'Hubo un error al actualizar el servicio.'; } header("Location:index.php?opt=listar_servicios"); exit; } // AGREGAR INSUMO AL SERVICIO (el post es atendido por CAJA) case 'agregar_insumo': // Verifico si es admin if (!$esAdmin) { header("Location: index.php?opt=inicio_operador"); exit; } // Guardo datos en $_SESSION para mantener persistencia de los datos if ($_SERVER['REQUEST_METHOD'] === 'POST') { $_SESSION['servicio']['detalle_realizado'] = $_POST['detalle_realizado'] ?? ''; $_SESSION['servicio']['mano_obra'] = (float) $_POST['mano_obra'] ?? 0; } $idServicio = (int) ($_GET['id'] ?? 0); // Requerimos modelo de producto require_once __DIR__ . '/../models/productoModel.php'; $productomodel = new productoModel(); $insumos = $productomodel->listarInsumosServicio(); foreach ($insumos as $j => $i) { if (!isset($i['id'])) { unset($insumos[$j]); continue; } if ($i['stock'] === null || $i['stock'] === 0) { $insumos[$j]['stock'] = '-'; } } ob_start(); require __DIR__ . '/../views/servicios/agregarInsumoServicioView.php'; return ob_get_clean(); // FINALIZACIÓN DE SERVICIO case 'finalizar_servicio': // Verifico si es admin if (!$esAdmin) { header("Location: index.php?opt=inicio_operador"); exit; } $idServicio = (int) ($_POST['id'] ?? 0); // VALIDACIONES if ($idServicio <= 0) { $_SESSION['flash_error'] = 'Datos inválidos.'; header('Location: index.php?opt=actualizar_servicio&id=' . $idServicio); exit; } // REQUERIMOS EL MODELO SERVICIO Y EL HELPER DEL MAIL require_once __DIR__ . '/../models/servicioModel.php'; require_once __DIR__ . '/../helpers/email_finalizado.php'; $serviciomodel = new servicioModel(); if ($serviciomodel->finalizarServicio($idServicio)) { $success = []; $success[] = "Servicio actualizado correctamente."; // OBTENEMOS DATOS DEL SERVICIO (SERVICIO, INSUMO UTILIZADOS Y CLIENTE) $servicio = $serviciomodel->getDetalleServicio($idServicio); $insumos = $serviciomodel->getDetalleInsumos($idServicio); $cliente = $serviciomodel->getClienteServicio($idServicio); // LLAMADA A MÉTODO PARA ENVÍO DE EMAIL $resultadoEnvioMail = enviarMailServicioFinalizado($servicio, $insumos, $cliente); // OBTENGO DATO DE CONFIGURACIÓN PARA DECIDIR QUE MENSAJE MOSTRAR $configuracionmodel = new configuracionModel(); $datosConfig = $configuracionmodel->obtenerDatosEnvioMail(); if (((int) $datosConfig['mail_automatico'] === 1) && $resultadoEnvioMail) { $success[] = "Email automático enviado correctamente."; } if (!$resultadoEnvioMail) { $success[] = "No fué posible enviar el email automático, por favor verifique manualmente."; } $_SESSION['flash_success'] = implode('
', $success); } else { $_SESSION['flash_error'] = $serviciomodel->getError() ?? 'Hubo un error al finalizar el servicio.'; } header("Location:index.php?opt=listar_servicios"); exit; // CANCELAR SERVICIO case 'cancelar_servicio': // Verifico si es admin if (!$esAdmin) { header("Location: index.php?opt=inicio_operador"); exit; } $idServicio = (int) ($_POST['id'] ?? 0); if ($idServicio <= 0) { $_SESSION['flash_error'] = 'Datos inválidos.'; header('Location: index.php?opt=listar_servicios'); exit; } // OBTENGO EL CARGO POR CANCELACIÓN DE SERVICIO (desde configuración) require_once __DIR__ . '/../models/configuracionModel.php'; $configuracionmodel = new configuracionModel(); $cargoCancelacion = $configuracionmodel->obtenerCargoCancelacion(); // Requiero modelo de servicio y llamo al método de cancelación require_once __DIR__ . '/../models/servicioModel.php'; $serviciomodel = new servicioModel(); if ($serviciomodel->cancelarServicio($idServicio, $cargoCancelacion)) { $_SESSION['flash_success'] = 'Servicio cancelado correctamente.'; } else { $_SESSION['flash_error'] = 'No se pudo cancelar el servicio.'; } header("Location:index.php?opt=listar_servicios"); exit; // VER EL DETALLE TOTAL DEL SERVICIO REALIZADO case 'detalle_servicio': $idServicio = (int) ($_GET['id'] ?? 0); require_once __DIR__ . '/../models/servicioModel.php'; $serviciomodel = new servicioModel(); $datosServicio = $serviciomodel->getDetalleServicio($idServicio); if (empty($datosServicio)) { $_SESSION['flash_error'] = "Hubo un error al cargar el detalle del servicio."; header("Location:index.php?opt=listar_servicios"); exit; } // Saneamiento de datos if ($datosServicio['detalle_realizado'] === null) { $datosServicio['detalle_realizado'] = ''; } if ($datosServicio['mano_obra'] === null) { $datosServicio['mano_obra'] = 0; } if ($datosServicio['total'] === null) { $datosServicio['total'] = 0; } // Desencriptacion de contraseñas if ($datosServicio['contrasenia_equipo'] !== null) { $datosServicio['contrasenia_equipo'] = decryptData($datosServicio['contrasenia_equipo']); } if ($datosServicio['contrasenia_cuenta'] !== null) { $datosServicio['contrasenia_cuenta'] = decryptData($datosServicio['contrasenia_cuenta']); } ob_start(); require_once __DIR__ . '/../views/servicios/detalleServicioView.php'; return ob_get_clean(); // MOSTRAR EL DETALLE DE INSUMOS case 'detalle_insumos_servicio': $idServicio = (int) ($_GET['id'] ?? 0); require_once __DIR__ . '/../models/servicioModel.php'; $serviciomodel = new servicioModel(); $servicio_detalle = $serviciomodel->getDetalleInsumos($idServicio); ob_start(); require_once __DIR__ . '/../views/servicios/detalleInsumosServicioView.php'; return ob_get_clean(); // ACTUALIZAR EL TOTAL AGREGANDO LA MANO DE OBRA case 'agregar_mano_obra': // Verifico si es admin if (!$esAdmin) { header("Location: index.php?opt=inicio_operador"); exit; } $idServicio = (int) ($_GET['id'] ?? 0); // Obtengo datos if ($_SERVER['REQUEST_METHOD'] === 'POST') { $detalleRealizado = $_POST['detalle_realizado'] ?? ''; $manoObra = (float) $_POST['mano_obra'] ?? 0; } if ($idServicio <= 0 || $manoObra < 0) { $_SESSION['flash_error'] = 'Datos inválidos.'; header('Location: index.php?opt=actualizar_servicio&id=' . $idServicio); exit; } $_SESSION['servicio']['detalle_realizado'] = $detalleRealizado; $_SESSION['servicio']['mano_obra'] = $manoObra; $_SESSION['flash_success'] = 'Mano de obra agregada correctamente.'; header('Location: index.php?opt=actualizar_servicio&id=' . $idServicio); exit; // DEFAULT (404) default: ob_start(); header("Location: index.php?opt=404View.php"); return ob_get_clean(); }