diff --git a/app/controllers/solicitud_importacion.php b/app/controllers/solicitud_importacion.php
index 9ceec94..6056769 100644
--- a/app/controllers/solicitud_importacion.php
+++ b/app/controllers/solicitud_importacion.php
@@ -796,4 +796,313 @@ function update_status() {
}
echo json_encode(['success'=>true]);
exit;
+}
+
+function pdf() {
+ // Verificar que se recibió el ID
+ if (!isset($_GET['id'])) {
+ http_response_code(400);
+ echo "ID de solicitud requerido";
+ return;
+ }
+
+ $id_solicitud = (int)$_GET['id'];
+
+ try {
+ // 1. Conexión
+ $conn = getConnection();
+
+ // 2. Obtener datos de la solicitud principal
+ $sql = "
+ SELECT
+ s.*,
+ i.nombre as importador_nombre,
+ i.rfc as importador_rfc,
+ i.calle,
+ i.num_exterior,
+ i.num_interior,
+ i.ciudad,
+ i.colonia,
+ i.codigo_postal,
+ i.estado,
+ i.telefono,
+ i.correo,
+ t.nombre as transportista_nombre,
+ c.nombre as chofer_nombre
+ FROM solicitud_importacion_factura s
+ LEFT JOIN informacion_general i ON s.id_importador = i.id_usuario
+ LEFT JOIN transportistas t ON s.transportista_id = t.id_transportista
+ LEFT JOIN choferes c ON s.chofer_id = c.id_chofer
+ WHERE s.id_solicitud = ?
+ ";
+
+ $params = array($id_solicitud);
+ $stmt = sqlsrv_query($conn, $sql, $params);
+
+ if ($stmt === false) {
+ throw new Exception("Error en la consulta: " . print_r(sqlsrv_errors(), true));
+ }
+
+ $solicitud = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
+ sqlsrv_free_stmt($stmt);
+
+ if (!$solicitud) {
+ http_response_code(404);
+ echo "Solicitud no encontrada";
+ return;
+ }
+
+ // 3. Obtener partidas de la solicitud
+ $sql = "
+ SELECT
+ p.*,
+ u.descripcion as unidad_descripcion
+ FROM solicitud_importacion_partidas p
+ LEFT JOIN unidades_medida_apendice7 u ON p.unidad_comercial_id = u.id
+ WHERE p.id_solicitud = ?
+ ORDER BY p.id_partida
+ ";
+
+ $params = array($id_solicitud);
+ $stmt = sqlsrv_query($conn, $sql, $params);
+
+ if ($stmt === false) {
+ throw new Exception("Error en la consulta de partidas: " . print_r(sqlsrv_errors(), true));
+ }
+
+ $partidas = array();
+ while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
+ $partidas[] = $row;
+ }
+ sqlsrv_free_stmt($stmt);
+
+ // 4. Configuración del sistema
+ global $config;
+ $nombre_sistema = $config['nombre_plataforma'] ?? 'Sistema Integral para Importadores de Hidrocarburos';
+ $siglas = $config['siglas'] ?? 'SIIH';
+ $logo_url = $config['logo_url'] ?? 'assets/img/logo_siih.png';
+
+ // 5. Generar HTML del PDF
+ $html = generarHTMLPDF($solicitud, $partidas, $nombre_sistema, $siglas, $logo_url);
+
+ // 6. Configurar headers para PDF
+ header('Content-Type: application/pdf');
+ header('Content-Disposition: inline; filename="solicitud_importacion_' . $id_solicitud . '.pdf"');
+
+ // 7. Generar PDF usando DomPDF
+ // Opción 1: DomPDF v0.8.x (compatible con PHP 5.x)
+ if (file_exists('lib/dompdf/dompdf-0.8.6/dompdf_config.inc.php')) {
+ require_once 'lib/dompdf/dompdf-0.8.6/dompdf_config.inc.php';
+
+ $dompdf = new DOMPDF();
+ $dompdf->load_html($html);
+ $dompdf->set_paper('A4', 'portrait');
+ $dompdf->render();
+
+ // Headers
+ header('Content-Type: application/pdf');
+ header('Content-Disposition: inline; filename="solicitud_importacion_' . $id_solicitud . '.pdf"');
+
+ echo $dompdf->output();
+
+ // Opción 2: DomPDF v1.x/2.x (PHP 7+)
+ } elseif (file_exists('vendor/autoload.php') && PHP_VERSION_ID >= 70000) {
+ require_once 'vendor/autoload.php';
+
+ $options = new \Dompdf\Options();
+ $options->set('defaultFont', 'Arial');
+ $options->set('isRemoteEnabled', true);
+
+ $dompdf = new \Dompdf\Dompdf($options);
+ $dompdf->loadHtml($html);
+ $dompdf->setPaper('A4', 'portrait');
+ $dompdf->render();
+
+ header('Content-Type: application/pdf');
+ header('Content-Disposition: inline; filename="solicitud_importacion_' . $id_solicitud . '.pdf"');
+
+ echo $dompdf->output();
+
+ // Opción 3: Alternativa usando mPDF (compatible con PHP 5.6+)
+ } elseif (file_exists('lib/mpdf/mpdf.php')) {
+ require_once 'lib/mpdf/mpdf.php';
+
+ $mpdf = new mPDF();
+ $mpdf->WriteHTML($html);
+ $mpdf->Output('solicitud_importacion_' . $id_solicitud . '.pdf', 'I');
+
+ // Opción 4: TCPDF (muy compatible)
+ } elseif (file_exists('lib/tcpdf/tcpdf.php')) {
+ require_once 'lib/tcpdf/tcpdf.php';
+
+ $pdf = new TCPDF();
+ $pdf->AddPage();
+ $pdf->writeHTML($html, true, false, true, false, '');
+ $pdf->Output('solicitud_importacion_' . $id_solicitud . '.pdf', 'I');
+
+ } else {
+ throw new Exception("No hay librerías PDF disponibles. Instala DomPDF, mPDF o TCPDF.");
+ }
+
+ } catch (Exception $e) {
+ error_log("Error generando PDF: " . $e->getMessage());
+ http_response_code(500);
+ echo "Error interno del servidor: " . $e->getMessage();
+ }
+}
+
+function generarHTMLPDF($solicitud, $partidas, $nombre_sistema, $siglas, $logo_url) {
+ // Formatear fecha
+ $fecha_expedicion = date('d/m/Y');
+ $fecha_factura = $solicitud['fecha_factura']->format('d/m/Y');
+ $fecha_vencimiento = (clone $solicitud['fecha_factura'])->modify('+30 days')->format('d/m/Y');
+
+
+ // Construir dirección del importador
+ $direccion_completa = trim(
+ ($solicitud['calle'] ?? '') . ' ' .
+ ($solicitud['num_exterior'] ?? '') . ' ' .
+ ($solicitud['num_interior'] ? 'Int. ' . $solicitud['num_interior'] : '') . ', ' .
+ ($solicitud['colonia'] ?? '') . ', ' .
+ ($solicitud['ciudad'] ?? '') . ', ' .
+ ($solicitud['estado'] ?? '') . ' ' .
+ ($solicitud['codigo_postal'] ?? '')
+ );
+
+ // Calcular totales
+ $subtotal = 0;
+ foreach ($partidas as $partida) {
+ $subtotal += (float)$partida['valor_factura'];
+ }
+ $descuento_pct = 0; // Puedes calcularlo si tienes descuentos
+ $descuento = $subtotal * ($descuento_pct / 100);
+ $total = $subtotal - $descuento;
+
+ $html = '
+
+
+
+
+ Solicitud de Importación
+
+
+
+
+
+
+
+
+
+
RAZÓN SOCIAL / ' . htmlspecialchars($solicitud['importador_nombre'] ?? 'No disponible') . '
+
DOMICILIO FISCAL: ' . htmlspecialchars($direccion_completa) . '
+
+
RFC: ' . htmlspecialchars($solicitud['importador_rfc'] ?? 'No disponible') . '
+
TELÉFONO: ' . htmlspecialchars($solicitud['telefono'] ?? 'No disponible') . '
+
+
+
RÉGIMEN FISCAL: 601-General de Ley Personas Morales
+
+
+
+
+
FECHA DE EXPEDICIÓN
+
' . $fecha_expedicion . '
+
FECHA DE VENCIMIENTO
+
' . $fecha_vencimiento . '
+
+
+
+
+
+
+
+ | Producto |
+ Unidad de Medida |
+ Precio Unitario |
+ Cantidad |
+ Descuento |
+ Total |
+
+
+ ';
+
+ // Agregar partidas
+ foreach ($partidas as $partida) {
+ $precio_unitario = (float)($partida['precio_unitario'] ?? 0);
+ $cantidad = (float)($partida['cantidad_comercial'] ?? 0);
+ $valor_partida = (float)($partida['valor_factura'] ?? 0);
+
+ $html .= '
+ | ' . htmlspecialchars($partida['descripcion']) . ' |
+ ' . htmlspecialchars($partida['unidad_descripcion'] ?? 'Unidad de servicio (E48)') . ' |
+ $' . number_format($precio_unitario > 0 ? $precio_unitario : $valor_partida, 2) . ' |
+ ' . number_format($cantidad > 0 ? $cantidad : 1, 0) . ' |
+ ' . number_format($descuento_pct, 1) . '% |
+ $' . number_format($valor_partida, 2) . ' |
+
';
+ }
+
+ $html .= '
+
+
+
+
+
+
+ Total:
+ $' . number_format($total, 2) . '
+
+
+
+
+
+
+
+';
+
+ return $html;
}
\ No newline at end of file
diff --git a/app/controllers/transportes.php b/app/controllers/transportes.php
index d2216b8..13c919f 100644
--- a/app/controllers/transportes.php
+++ b/app/controllers/transportes.php
@@ -217,13 +217,13 @@ function eliminar() {
exit;
}
-
/** Formulario de importación masiva **/
function masivo() {
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
+
include __DIR__ . '/../../views/transportes/importar_masivo.php';
}
diff --git a/views/admin/alta_usuarios.php b/views/admin/alta_usuarios.php
index 673106a..9502b1a 100644
--- a/views/admin/alta_usuarios.php
+++ b/views/admin/alta_usuarios.php
@@ -1,3 +1,5 @@
+
+
@@ -6,137 +8,123 @@
-
-
-
-
+
+
Administración de Usuarios
-include __DIR__ . '/../partials/sidebar_sistemas.php';
-?>
+
+
-
-
-
Administración de Usuarios
-
-
-
-
-
-
-
👁️ Usuarios Registrados
-
-
-
-
- | # |
- Nombre |
- Correo |
- Tipo |
- Estado |
- Acciones |
-
-
-
-
-
+
+
+
👁️ Usuarios Registrados
+
+
+
- | = $u['id_usuario'] ?> |
- = decrypt($u['nombre']) ?> |
- = decrypt($u['email']) ?> |
- = ucfirst($u['tipo_usuario']) ?> |
-
-
- = $u['activo'] ? 'Activo' : 'Inactivo' ?>
-
- |
-
- Toggle
- Reset
- |
+ # |
+ Nombre |
+ Correo |
+ Tipo |
+ Estado |
+ Acciones |
-
-
-
- | No hay usuarios registrados aún. |
-
-
-
-
+
+
+
+
+
+ | = $u['id_usuario'] ?> |
+ = decrypt($u['nombre']) ?> |
+ = decrypt($u['email']) ?> |
+ = ucfirst($u['tipo_usuario']) ?> |
+
+
+ = $u['activo'] ? 'Activo' : 'Inactivo' ?>
+
+ |
+
+ Toggle
+ Reset
+ |
+
+
+
+
+ | No hay usuarios registrados aún. |
+
+
+
+
+
-
+
+
+
-
-
-
-
-
-
+ function copiarPassword() {
+ navigator.clipboard.writeText(nuevaPassword).then(() => {
+ Swal.fire('Copiado', 'La contraseña fue copiada al portapapeles.', 'success');
+ });
+ }
+ function enviarPorCorreo() {
+ fetch(`/IMPORTADORES/sistemas/enviar_password?email=${encodeURIComponent(emailUsuario)}&pass=${encodeURIComponent(nuevaPassword)}`)
+ .then(response => response.text())
+ .then(data => {
+ Swal.fire('Enviado', 'La contraseña fue enviada al correo del usuario.', 'success');
+ })
+ .catch(() => {
+ Swal.fire('Error', 'No se pudo enviar el correo.', 'error');
+ });
+ }
+
+
-
+