" ."

Acuse de Manifestación de Valor

" ."

Pedimento: {$display}

" ."

RFC: ".htmlspecialchars($ped['rfc_importador'] ?? '-', ENT_QUOTES, 'UTF-8')."

" ."

Clave: ".htmlspecialchars($ped['clave_documento'] ?? '-', ENT_QUOTES, 'UTF-8')."

" ."

Generado: {$now}

" ."

Documento de prueba generado automáticamente.

" .""; $htmlDetalle = "" ."

Detalle de Manifestación de Valor

" ."

Pedimento: {$display}

" ."

Este es un detalle de ejemplo para pruebas.

" ."" ."

Generado: {$now}

" .""; // Intentar generar PDF con Dompdf; fallback a .txt si no está disponible $docs = [ [ 'nombre' => 'Acuse Manifestacion de Valor', 'html' => $htmlAcuse ], [ 'nombre' => 'Detalle Manifestacion de Valor', 'html' => $htmlDetalle ], ]; $dompdfOk = false; try { @require_once __DIR__ . '/../../vendor/autoload.php'; if (class_exists('Dompdf\\Dompdf')) { $dompdfOk = true; } } catch (\Throwable $e) { $dompdfOk = false; } foreach ($docs as $d) { $safeBase = preg_replace('/[^A-Za-z0-9._\- ]/', '_', $d['nombre']); $filename = $safeBase . '_' . time() . ($dompdfOk ? '.pdf' : '.txt'); $fullPath = $uploadDir . '/' . $filename; $rutaDb = 'uploads/expedientes/' . $folderKey . '/' . $filename; if ($dompdfOk) { try { $dompdf = new Dompdf\Dompdf([ 'isRemoteEnabled' => false ]); $dompdf->loadHtml($d['html']); $dompdf->setPaper('letter', 'portrait'); $dompdf->render(); file_put_contents($fullPath, $dompdf->output()); $tipo = 'application/pdf'; } catch (\Throwable $e) { // Fallback a texto file_put_contents($fullPath, strip_tags($d['html'])); $tipo = 'text/plain'; } } else { file_put_contents($fullPath, strip_tags($d['html'])); $tipo = 'text/plain'; } $tamanoKb = file_exists($fullPath) ? round(filesize($fullPath) / 1024, 2) : 0; // Insertar en expediente_archivos sqlsrv_query($conn, "INSERT INTO expediente_archivos (pedimento_id, nombre_archivo, ruta_archivo, tipo_archivo, tamano_archivo, creado_por) VALUES (?,?,?,?,?,?)", [$pedimento_id, $d['nombre'] . ($dompdfOk ? '.pdf' : '.txt'), $rutaDb, $tipo, $tamanoKb, $usuario_nombre] ); } } function index() { include __DIR__ . '/../../views/mve/lista.php'; } // Guarda en bloque los datos enviados (se usa por el botón Guardar) function ajax_guardar_datos_factura() { if (!($_SESSION['usuario_id'] ?? false)) { echo json_encode(['success' => false, 'message' => 'No autorizado']); return; } $usuario_id = (int)$_SESSION['usuario_id']; $id_factura = isset($_POST['id_factura']) ? (int)$_POST['id_factura'] : 0; $id_pedimento = isset($_POST['id_pedimento']) ? (int)$_POST['id_pedimento'] : 0; $datos_art65 = json_decode($_POST['datos_art65'] ?? '{}', true); $datos_art66 = json_decode($_POST['datos_art66'] ?? '{}', true); $datos_precio_pagado = json_decode($_POST['datos_precio_pagado'] ?? '{}', true); $datos_precio_pagar = json_decode($_POST['datos_precio_pagar'] ?? '{}', true); $datos_compenso = json_decode($_POST['datos_compenso'] ?? '{}', true); if ($id_factura <= 0 || $id_pedimento <= 0) { echo json_encode(['success' => false, 'message' => 'Parámetros inválidos']); return; } $conn = getConnection(); // Verificar propiedad del pedimento y que la factura le pertenezca $chk = sqlsrv_query($conn, "SELECT 1 FROM pedimentos p JOIN pedimento_facturas f ON f.pedimento_id = p.id WHERE p.id = ? AND f.id = ? AND p.usuario_id = ?", [$id_pedimento, $id_factura, $usuario_id]); $own = $chk && sqlsrv_fetch_array($chk) ? true : false; if ($chk) sqlsrv_free_stmt($chk); if (!$own) { echo json_encode(['success' => false, 'message' => 'No autorizado o no encontrado']); return; } // ¿Existe registro para esta factura? $sel = sqlsrv_query($conn, "SELECT id FROM mve_facturas_datos WHERE id_pedimento = ? AND id_factura = ?", [$id_pedimento, $id_factura]); $row = $sel ? sqlsrv_fetch_array($sel, SQLSRV_FETCH_ASSOC) : null; if ($sel) sqlsrv_free_stmt($sel); if ($row) { // UPDATE $sql = "UPDATE mve_facturas_datos SET art65_fecha_transporte = ?, art65_importe_transporte = ?, art65_fecha_descuentos = ?, art65_importe_descuentos = ?, art65_fecha_posteriores = ?, art65_importe_posteriores = ?, art65_fecha_contribuciones = ?, art65_importe_contribuciones = ?, art65_fecha_pagos_vendedor = ?, art65_importe_pagos_vendedor = ?, art66_fecha_comisiones = ?, art66_importe_comisiones = ?, art66_cargo_comisiones = ?, art66_fecha_envases = ?, art66_importe_envases = ?, art66_cargo_envases = ?, art66_fecha_embalaje = ?, art66_importe_embalaje = ?, art66_cargo_embalaje = ?, art66_fecha_transporte_dec = ?, art66_importe_transporte_dec = ?, art66_cargo_transporte_dec = ?, art66_fecha_ingenieria = ?, art66_importe_ingenieria = ?, art66_cargo_ingenieria = ?, art66_fecha_regalias = ?, art66_importe_regalias = ?, art66_cargo_regalias = ?, art66_fecha_producto = ?, art66_importe_producto = ?, art66_cargo_producto = ?, precio_pagado_fecha_pago = ?, precio_pagado_importe = ?, precio_pagado_moneda = ?, precio_pagado_forma_pago = ?, precio_pagado_referencia = ?, precio_pagar_fecha_limite = ?, precio_pagar_importe = ?, precio_pagar_moneda = ?, precio_pagar_terminos = ?, precio_pagar_observaciones = ?, compenso_fecha = ?, compenso_importe = ?, compenso_tipo = ?, compenso_motivo = ?, compenso_documentos = ?, compenso_descripcion = ? WHERE id = ?"; $params = [ $datos_art65['fecha_transporte'] ?? null, $datos_art65['importe_transporte'] ?? null, $datos_art65['fecha_descuentos'] ?? null, $datos_art65['importe_descuentos'] ?? null, $datos_art65['fecha_posteriores'] ?? null, $datos_art65['importe_posteriores'] ?? null, $datos_art65['fecha_contribuciones'] ?? null, $datos_art65['importe_contribuciones'] ?? null, $datos_art65['fecha_pagos_vendedor'] ?? null, $datos_art65['importe_pagos_vendedor'] ?? null, $datos_art66['fecha_comisiones'] ?? null, $datos_art66['importe_comisiones'] ?? null, $datos_art66['cargo_comisiones'] ?? null, $datos_art66['fecha_envases'] ?? null, $datos_art66['importe_envases'] ?? null, $datos_art66['cargo_envases'] ?? null, $datos_art66['fecha_embalaje'] ?? null, $datos_art66['importe_embalaje'] ?? null, $datos_art66['cargo_embalaje'] ?? null, $datos_art66['fecha_transporte_dec'] ?? null, $datos_art66['importe_transporte_dec'] ?? null, $datos_art66['cargo_transporte_dec'] ?? null, $datos_art66['fecha_ingenieria'] ?? null, $datos_art66['importe_ingenieria'] ?? null, $datos_art66['cargo_ingenieria'] ?? null, $datos_art66['fecha_regalias'] ?? null, $datos_art66['importe_regalias'] ?? null, $datos_art66['cargo_regalias'] ?? null, $datos_art66['fecha_producto'] ?? null, $datos_art66['importe_producto'] ?? null, $datos_art66['cargo_producto'] ?? null, $datos_precio_pagado['fecha_precio_pagado'] ?? null, $datos_precio_pagado['importe_precio_pagado'] ?? null, $datos_precio_pagado['moneda_precio_pagado'] ?? null, $datos_precio_pagado['forma_pago_precio_pagado'] ?? null, $datos_precio_pagado['referencia_precio_pagado'] ?? null, $datos_precio_pagar['fecha_limite_pago'] ?? null, $datos_precio_pagar['importe_precio_pagar'] ?? null, $datos_precio_pagar['moneda_precio_pagar'] ?? null, $datos_precio_pagar['terminos_precio_pagar'] ?? null, $datos_precio_pagar['observaciones_precio_pagar'] ?? null, $datos_compenso['fecha_compenso'] ?? null, $datos_compenso['importe_compenso'] ?? null, $datos_compenso['tipo_compenso'] ?? null, $datos_compenso['motivo_compenso'] ?? null, $datos_compenso['documentos_compenso'] ?? null, $datos_compenso['descripcion_compenso'] ?? null, $row['id'] ]; $stmt = sqlsrv_query($conn, $sql, $params); } else { // INSERT $sql = "INSERT INTO mve_facturas_datos ( id_pedimento, id_factura, numero_factura, art65_fecha_transporte, art65_importe_transporte, art65_fecha_descuentos, art65_importe_descuentos, art65_fecha_posteriores, art65_importe_posteriores, art65_fecha_contribuciones, art65_importe_contribuciones, art65_fecha_pagos_vendedor, art65_importe_pagos_vendedor, art66_fecha_comisiones, art66_importe_comisiones, art66_cargo_comisiones, art66_fecha_envases, art66_importe_envases, art66_cargo_envases, art66_fecha_embalaje, art66_importe_embalaje, art66_cargo_embalaje, art66_fecha_transporte_dec, art66_importe_transporte_dec, art66_cargo_transporte_dec, art66_fecha_ingenieria, art66_importe_ingenieria, art66_cargo_ingenieria, art66_fecha_regalias, art66_importe_regalias, art66_cargo_regalias, art66_fecha_producto, art66_importe_producto, art66_cargo_producto, precio_pagado_fecha_pago, precio_pagado_importe, precio_pagado_moneda, precio_pagado_forma_pago, precio_pagado_referencia, precio_pagar_fecha_limite, precio_pagar_importe, precio_pagar_moneda, precio_pagar_terminos, precio_pagar_observaciones, compenso_fecha, compenso_importe, compenso_tipo, compenso_motivo, compenso_documentos, compenso_descripcion, usuario_creacion ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; // Obtener número de factura opcional $num = null; $nf = sqlsrv_query($conn, "SELECT numero_factura FROM pedimento_facturas WHERE id = ?", [$id_factura]); if ($nf && ($r = sqlsrv_fetch_array($nf, SQLSRV_FETCH_ASSOC))) { $num = $r['numero_factura']; } if ($nf) sqlsrv_free_stmt($nf); $params = [ $id_pedimento, $id_factura, $num, $datos_art65['fecha_transporte'] ?? null, $datos_art65['importe_transporte'] ?? null, $datos_art65['fecha_descuentos'] ?? null, $datos_art65['importe_descuentos'] ?? null, $datos_art65['fecha_posteriores'] ?? null, $datos_art65['importe_posteriores'] ?? null, $datos_art65['fecha_contribuciones'] ?? null, $datos_art65['importe_contribuciones'] ?? null, $datos_art65['fecha_pagos_vendedor'] ?? null, $datos_art65['importe_pagos_vendedor'] ?? null, $datos_art66['fecha_comisiones'] ?? null, $datos_art66['importe_comisiones'] ?? null, $datos_art66['cargo_comisiones'] ?? null, $datos_art66['fecha_envases'] ?? null, $datos_art66['importe_envases'] ?? null, $datos_art66['cargo_envases'] ?? null, $datos_art66['fecha_embalaje'] ?? null, $datos_art66['importe_embalaje'] ?? null, $datos_art66['cargo_embalaje'] ?? null, $datos_art66['fecha_transporte_dec'] ?? null, $datos_art66['importe_transporte_dec'] ?? null, $datos_art66['cargo_transporte_dec'] ?? null, $datos_art66['fecha_ingenieria'] ?? null, $datos_art66['importe_ingenieria'] ?? null, $datos_art66['cargo_ingenieria'] ?? null, $datos_art66['fecha_regalias'] ?? null, $datos_art66['importe_regalias'] ?? null, $datos_art66['cargo_regalias'] ?? null, $datos_art66['fecha_producto'] ?? null, $datos_art66['importe_producto'] ?? null, $datos_art66['cargo_producto'] ?? null, $datos_precio_pagado['fecha_precio_pagado'] ?? null, $datos_precio_pagado['importe_precio_pagado'] ?? null, $datos_precio_pagado['moneda_precio_pagado'] ?? null, $datos_precio_pagado['forma_pago_precio_pagado'] ?? null, $datos_precio_pagado['referencia_precio_pagado'] ?? null, $datos_precio_pagar['fecha_limite_pago'] ?? null, $datos_precio_pagar['importe_precio_pagar'] ?? null, $datos_precio_pagar['moneda_precio_pagar'] ?? null, $datos_precio_pagar['terminos_precio_pagar'] ?? null, $datos_precio_pagar['observaciones_precio_pagar'] ?? null, $datos_compenso['fecha_compenso'] ?? null, $datos_compenso['importe_compenso'] ?? null, $datos_compenso['tipo_compenso'] ?? null, $datos_compenso['motivo_compenso'] ?? null, $datos_compenso['documentos_compenso'] ?? null, $datos_compenso['descripcion_compenso'] ?? null, (string)$usuario_id ]; $stmt = sqlsrv_query($conn, $sql, $params); } if ($stmt === false) { echo json_encode(['success' => false, 'message' => 'Error al guardar']); return; } // Marcar estado de MVE/COVE como respondido (para el badge) upsert_cove_respuesta_min($conn, $id_pedimento, $id_factura, $usuario_id); echo json_encode(['success' => true]); } // Autosave por sección: seccion in ['65','66','precio_pagado','precio_pagar','compenso'] function ajax_guardar_seccion() { if (!($_SESSION['usuario_id'] ?? false)) { echo json_encode(['success' => false, 'message' => 'No autorizado']); return; } $usuario_id = (int)$_SESSION['usuario_id']; $id_factura = isset($_POST['id_factura']) ? (int)$_POST['id_factura'] : 0; $id_pedimento = isset($_POST['id_pedimento']) ? (int)$_POST['id_pedimento'] : 0; $seccion = $_POST['seccion'] ?? ''; $datos = json_decode($_POST['datos'] ?? '{}', true); if ($id_factura <= 0 || $id_pedimento <= 0 || !$seccion) { echo json_encode(['success' => false, 'message' => 'Parámetros inválidos']); return; } $conn = getConnection(); // Verificar propiedad $chk = sqlsrv_query($conn, "SELECT 1 FROM pedimentos p JOIN pedimento_facturas f ON f.pedimento_id = p.id WHERE p.id = ? AND f.id = ? AND p.usuario_id = ?", [$id_pedimento, $id_factura, $usuario_id]); $own = $chk && sqlsrv_fetch_array($chk) ? true : false; if ($chk) sqlsrv_free_stmt($chk); if (!$own) { echo json_encode(['success' => false, 'message' => 'No autorizado']); return; } // Garantizar que exista el registro base $sel = sqlsrv_query($conn, "SELECT id FROM mve_facturas_datos WHERE id_pedimento = ? AND id_factura = ?", [$id_pedimento, $id_factura]); $row = $sel ? sqlsrv_fetch_array($sel, SQLSRV_FETCH_ASSOC) : null; if ($sel) sqlsrv_free_stmt($sel); if (!$row) { // Crear registro vacío $num = null; $nf = sqlsrv_query($conn, "SELECT numero_factura FROM pedimento_facturas WHERE id = ?", [$id_factura]); if ($nf && ($r = sqlsrv_fetch_array($nf, SQLSRV_FETCH_ASSOC))) { $num = $r['numero_factura']; } if ($nf) sqlsrv_free_stmt($nf); $ins = sqlsrv_query($conn, "INSERT INTO mve_facturas_datos (id_pedimento, id_factura, numero_factura, usuario_creacion) VALUES (?,?,?,?)", [$id_pedimento, $id_factura, $num, (string)$usuario_id]); if ($ins === false) { echo json_encode(['success' => false, 'message' => 'Error al iniciar registro']); return; } $sel2 = sqlsrv_query($conn, "SELECT id FROM mve_facturas_datos WHERE id_pedimento = ? AND id_factura = ?", [$id_pedimento, $id_factura]); $row = $sel2 ? sqlsrv_fetch_array($sel2, SQLSRV_FETCH_ASSOC) : null; if ($sel2) sqlsrv_free_stmt($sel2); } if (!$row) { echo json_encode(['success' => false, 'message' => 'No se pudo crear el registro']); return; } $id = (int)$row['id']; $sql = ''; $params = []; switch ($seccion) { case '65': $sql = "UPDATE mve_facturas_datos SET art65_fecha_transporte = ?, art65_importe_transporte = ?, art65_fecha_descuentos = ?, art65_importe_descuentos = ?, art65_fecha_posteriores = ?, art65_importe_posteriores = ?, art65_fecha_contribuciones = ?, art65_importe_contribuciones = ?, art65_fecha_pagos_vendedor = ?, art65_importe_pagos_vendedor = ? WHERE id = ?"; $params = [ $datos['fecha_transporte'] ?? null, $datos['importe_transporte'] ?? null, $datos['fecha_descuentos'] ?? null, $datos['importe_descuentos'] ?? null, $datos['fecha_posteriores'] ?? null, $datos['importe_posteriores'] ?? null, $datos['fecha_contribuciones'] ?? null, $datos['importe_contribuciones'] ?? null, $datos['fecha_pagos_vendedor'] ?? null, $datos['importe_pagos_vendedor'] ?? null, $id ]; break; case '66': $sql = "UPDATE mve_facturas_datos SET art66_fecha_comisiones = ?, art66_importe_comisiones = ?, art66_cargo_comisiones = ?, art66_fecha_envases = ?, art66_importe_envases = ?, art66_cargo_envases = ?, art66_fecha_embalaje = ?, art66_importe_embalaje = ?, art66_cargo_embalaje = ?, art66_fecha_transporte_dec = ?, art66_importe_transporte_dec = ?, art66_cargo_transporte_dec = ?, art66_fecha_ingenieria = ?, art66_importe_ingenieria = ?, art66_cargo_ingenieria = ?, art66_fecha_regalias = ?, art66_importe_regalias = ?, art66_cargo_regalias = ?, art66_fecha_producto = ?, art66_importe_producto = ?, art66_cargo_producto = ? WHERE id = ?"; $params = [ $datos['fecha_comisiones'] ?? null, $datos['importe_comisiones'] ?? null, $datos['cargo_comisiones'] ?? null, $datos['fecha_envases'] ?? null, $datos['importe_envases'] ?? null, $datos['cargo_envases'] ?? null, $datos['fecha_embalaje'] ?? null, $datos['importe_embalaje'] ?? null, $datos['cargo_embalaje'] ?? null, $datos['fecha_transporte_dec'] ?? null, $datos['importe_transporte_dec'] ?? null, $datos['cargo_transporte_dec'] ?? null, $datos['fecha_ingenieria'] ?? null, $datos['importe_ingenieria'] ?? null, $datos['cargo_ingenieria'] ?? null, $datos['fecha_regalias'] ?? null, $datos['importe_regalias'] ?? null, $datos['cargo_regalias'] ?? null, $datos['fecha_producto'] ?? null, $datos['importe_producto'] ?? null, $datos['cargo_producto'] ?? null, $id ]; break; case 'precio_pagado': $sql = "UPDATE mve_facturas_datos SET precio_pagado_fecha_pago = ?, precio_pagado_importe = ?, precio_pagado_moneda = ?, precio_pagado_forma_pago = ?, precio_pagado_referencia = ? WHERE id = ?"; $params = [ $datos['fecha_precio_pagado'] ?? null, $datos['importe_precio_pagado'] ?? null, $datos['moneda_precio_pagado'] ?? null, $datos['forma_pago_precio_pagado'] ?? null, $datos['referencia_precio_pagado'] ?? null, $id ]; break; case 'precio_pagar': $sql = "UPDATE mve_facturas_datos SET precio_pagar_fecha_limite = ?, precio_pagar_importe = ?, precio_pagar_moneda = ?, precio_pagar_terminos = ?, precio_pagar_observaciones = ? WHERE id = ?"; $params = [ $datos['fecha_limite_pago'] ?? null, $datos['importe_precio_pagar'] ?? null, $datos['moneda_precio_pagar'] ?? null, $datos['terminos_precio_pagar'] ?? null, $datos['observaciones_precio_pagar'] ?? null, $id ]; break; case 'compenso': $sql = "UPDATE mve_facturas_datos SET compenso_fecha = ?, compenso_importe = ?, compenso_tipo = ?, compenso_motivo = ?, compenso_documentos = ?, compenso_descripcion = ? WHERE id = ?"; $params = [ $datos['fecha_compenso'] ?? null, $datos['importe_compenso'] ?? null, $datos['tipo_compenso'] ?? null, $datos['motivo_compenso'] ?? null, $datos['documentos_compenso'] ?? null, $datos['descripcion_compenso'] ?? null, $id ]; break; default: echo json_encode(['success' => false, 'message' => 'Sección inválida']); return; } $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt === false) { echo json_encode(['success' => false, 'message' => 'Error al guardar sección']); return; } // Marcar estado para badge upsert_cove_respuesta_min($conn, $id_pedimento, $id_factura, $usuario_id); echo json_encode(['success' => true]); } function ajax_obtener_datos_factura() { $id_factura = isset($_GET['id_factura']) ? (int)$_GET['id_factura'] : 0; if ($id_factura <= 0) { echo json_encode(['success' => false, 'message' => 'ID inválido']); return; } $conn = getConnection(); $stmt = sqlsrv_query($conn, "SELECT * FROM mve_facturas_datos WHERE id_factura = ?", [$id_factura]); if ($stmt === false) { echo json_encode(['success' => false, 'message' => 'Error DB']); return; } $datos = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); if ($stmt) sqlsrv_free_stmt($stmt); if ($datos) { // Formateador de fechas seguro para JSON $fmtDate = function($v) { if ($v instanceof DateTime) return $v->format('Y-m-d'); if (is_string($v)) return substr($v, 0, 10); return $v ?: null; }; if (isset($datos['fecha_actualizacion']) && $datos['fecha_actualizacion'] instanceof DateTime) { $datos['fecha_actualizacion'] = $datos['fecha_actualizacion']->format('Y-m-d H:i:s'); } $datosEstructurados = [ 'art65' => [ 'fecha_transporte' => $fmtDate($datos['art65_fecha_transporte'] ?? null), 'importe_transporte' => $datos['art65_importe_transporte'] ?? null, 'fecha_descuentos' => $fmtDate($datos['art65_fecha_descuentos'] ?? null), 'importe_descuentos' => $datos['art65_importe_descuentos'] ?? null, 'fecha_posteriores' => $fmtDate($datos['art65_fecha_posteriores'] ?? null), 'importe_posteriores' => $datos['art65_importe_posteriores'] ?? null, 'fecha_contribuciones' => $fmtDate($datos['art65_fecha_contribuciones'] ?? null), 'importe_contribuciones' => $datos['art65_importe_contribuciones'] ?? null, 'fecha_pagos_vendedor' => $fmtDate($datos['art65_fecha_pagos_vendedor'] ?? null), 'importe_pagos_vendedor' => $datos['art65_importe_pagos_vendedor'] ?? null, ], 'art66' => [ 'fecha_comisiones' => $fmtDate($datos['art66_fecha_comisiones'] ?? null), 'importe_comisiones' => $datos['art66_importe_comisiones'] ?? null, 'cargo_comisiones' => $datos['art66_cargo_comisiones'] ?? null, 'fecha_envases' => $fmtDate($datos['art66_fecha_envases'] ?? null), 'importe_envases' => $datos['art66_importe_envases'] ?? null, 'cargo_envases' => $datos['art66_cargo_envases'] ?? null, 'fecha_embalaje' => $fmtDate($datos['art66_fecha_embalaje'] ?? null), 'importe_embalaje' => $datos['art66_importe_embalaje'] ?? null, 'cargo_embalaje' => $datos['art66_cargo_embalaje'] ?? null, 'fecha_transporte_dec' => $fmtDate($datos['art66_fecha_transporte_dec'] ?? null), 'importe_transporte_dec' => $datos['art66_importe_transporte_dec'] ?? null, 'cargo_transporte_dec' => $datos['art66_cargo_transporte_dec'] ?? null, 'fecha_ingenieria' => $fmtDate($datos['art66_fecha_ingenieria'] ?? null), 'importe_ingenieria' => $datos['art66_importe_ingenieria'] ?? null, 'cargo_ingenieria' => $datos['art66_cargo_ingenieria'] ?? null, 'fecha_regalias' => $fmtDate($datos['art66_fecha_regalias'] ?? null), 'importe_regalias' => $datos['art66_importe_regalias'] ?? null, 'cargo_regalias' => $datos['art66_cargo_regalias'] ?? null, 'fecha_producto' => $fmtDate($datos['art66_fecha_producto'] ?? null), 'importe_producto' => $datos['art66_importe_producto'] ?? null, 'cargo_producto' => $datos['art66_cargo_producto'] ?? null, ], 'precio_pagado' => [ 'fecha_precio_pagado' => $fmtDate($datos['precio_pagado_fecha_pago'] ?? null), 'importe_precio_pagado' => $datos['precio_pagado_importe'] ?? null, 'moneda_precio_pagado' => $datos['precio_pagado_moneda'] ?? null, 'forma_pago_precio_pagado' => $datos['precio_pagado_forma_pago'] ?? null, 'referencia_precio_pagado' => $datos['precio_pagado_referencia'] ?? null, ], 'precio_pagar' => [ 'fecha_limite_pago' => $fmtDate($datos['precio_pagar_fecha_limite'] ?? null), 'importe_precio_pagar' => $datos['precio_pagar_importe'] ?? null, 'moneda_precio_pagar' => $datos['precio_pagar_moneda'] ?? null, 'terminos_precio_pagar' => $datos['precio_pagar_terminos'] ?? null, 'observaciones_precio_pagar' => $datos['precio_pagar_observaciones'] ?? null, ], 'compenso' => [ 'fecha_compenso' => $fmtDate($datos['compenso_fecha'] ?? null), 'importe_compenso' => $datos['compenso_importe'] ?? null, 'tipo_compenso' => $datos['compenso_tipo'] ?? null, 'motivo_compenso' => $datos['compenso_motivo'] ?? null, 'documentos_compenso' => $datos['compenso_documentos'] ?? null, 'descripcion_compenso' => $datos['compenso_descripcion'] ?? null, ] ]; echo json_encode(['success' => true, 'datos' => $datosEstructurados]); } else { echo json_encode(['success' => true, 'datos' => null]); } } // Utilidad: marca/crea un registro mínimo en cove_respuestas para encender el badge function upsert_cove_respuesta_min($conn, $pedimento_id, $factura_id, $usuario_id) { $sel = sqlsrv_query($conn, "SELECT id FROM cove_respuestas WHERE factura_id = ? AND usuario_id = ?", [$factura_id, $usuario_id]); $row = $sel ? sqlsrv_fetch_array($sel, SQLSRV_FETCH_ASSOC) : null; if ($sel) sqlsrv_free_stmt($sel); if ($row) { sqlsrv_query($conn, "UPDATE cove_respuestas SET estado = 'respondido', fecha_actualizacion = SYSDATETIME() WHERE id = ?", [$row['id']]); } else { sqlsrv_query($conn, "INSERT INTO cove_respuestas (pedimento_id, factura_id, usuario_id, respuestas, estado, fecha_creacion) VALUES (?,?,?,?,?,SYSDATETIME())", [$pedimento_id, $factura_id, $usuario_id, '{}', 'respondido']); } } // Registra la solicitud de MVE con aceptación de declaración del importador function ajax_registrar_solicitud() { header('Content-Type: application/json; charset=UTF-8'); if (!($_SESSION['usuario_id'] ?? false)) { http_response_code(403); echo json_encode(['success' => false, 'message' => 'No autorizado']); return; } $usuario_id = (int)$_SESSION['usuario_id']; $pedimento_id = isset($_POST['pedimento_id']) ? (int)$_POST['pedimento_id'] : 0; $factura_id = isset($_POST['factura_id']) ? (int)$_POST['factura_id'] : 0; $acepto = isset($_POST['acepto']) ? (int)$_POST['acepto'] : 0; $rfc_importador = isset($_POST['rfc_importador']) ? trim($_POST['rfc_importador']) : null; $firma_base64 = isset($_POST['firma_base64']) ? $_POST['firma_base64'] : null; $firmante = isset($_POST['firmante']) ? trim($_POST['firmante']) : null; $ip = $_SERVER['REMOTE_ADDR'] ?? null; if ($pedimento_id <= 0 || $factura_id <= 0) { echo json_encode(['success' => false, 'message' => 'Parámetros inválidos']); return; } if ($acepto !== 1) { echo json_encode(['success' => false, 'message' => 'Debes aceptar la declaración']); return; } $conn = getConnection(); // Verificar propiedad y relación factura-pedimento $chk = sqlsrv_query($conn, "SELECT 1 FROM pedimentos p JOIN pedimento_facturas f ON f.pedimento_id = p.id WHERE p.id = ? AND f.id = ? AND p.usuario_id = ?", [$pedimento_id, $factura_id, $usuario_id]); $ok = $chk && sqlsrv_fetch_array($chk) ? true : false; if ($chk) sqlsrv_free_stmt($chk); if (!$ok) { echo json_encode(['success' => false, 'message' => 'No autorizado o relación inválida']); return; } // Asegurar tabla mve_solicitudes $sqlEnsure = " IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mve_solicitudes]') AND type in (N'U')) BEGIN CREATE TABLE dbo.mve_solicitudes ( id INT IDENTITY(1,1) PRIMARY KEY, pedimento_id INT NOT NULL, factura_id INT NOT NULL, usuario_id INT NOT NULL, acepto_declaracion BIT NOT NULL, rfc_importador NVARCHAR(20) NULL, ip NVARCHAR(64) NULL, fecha_solicitud DATETIME2 NOT NULL DEFAULT SYSDATETIME(), comentario NVARCHAR(400) NULL, firma_base64 NVARCHAR(MAX) NULL, firmante NVARCHAR(200) NULL ); CREATE INDEX IX_mve_solicitudes_factura ON dbo.mve_solicitudes(factura_id); END; -- Ensure all expected columns exist on legacy tables IF COL_LENGTH('dbo.mve_solicitudes','pedimento_id') IS NULL ALTER TABLE dbo.mve_solicitudes ADD pedimento_id INT NULL; IF COL_LENGTH('dbo.mve_solicitudes','factura_id') IS NULL ALTER TABLE dbo.mve_solicitudes ADD factura_id INT NULL; IF COL_LENGTH('dbo.mve_solicitudes','usuario_id') IS NULL ALTER TABLE dbo.mve_solicitudes ADD usuario_id INT NULL; IF COL_LENGTH('dbo.mve_solicitudes','acepto_declaracion') IS NULL ALTER TABLE dbo.mve_solicitudes ADD acepto_declaracion BIT NULL; IF COL_LENGTH('dbo.mve_solicitudes','rfc_importador') IS NULL ALTER TABLE dbo.mve_solicitudes ADD rfc_importador NVARCHAR(20) NULL; IF COL_LENGTH('dbo.mve_solicitudes','ip') IS NULL ALTER TABLE dbo.mve_solicitudes ADD ip NVARCHAR(64) NULL; IF COL_LENGTH('dbo.mve_solicitudes','fecha_solicitud') IS NULL ALTER TABLE dbo.mve_solicitudes ADD fecha_solicitud DATETIME2 NULL; IF COL_LENGTH('dbo.mve_solicitudes','comentario') IS NULL ALTER TABLE dbo.mve_solicitudes ADD comentario NVARCHAR(400) NULL; IF COL_LENGTH('dbo.mve_solicitudes', 'firma_base64') IS NULL ALTER TABLE dbo.mve_solicitudes ADD firma_base64 NVARCHAR(MAX) NULL; IF COL_LENGTH('dbo.mve_solicitudes', 'firmante') IS NULL ALTER TABLE dbo.mve_solicitudes ADD firmante NVARCHAR(200) NULL; IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_mve_solicitudes_factura' AND object_id = OBJECT_ID('dbo.mve_solicitudes')) CREATE INDEX IX_mve_solicitudes_factura ON dbo.mve_solicitudes(factura_id); "; $ensureOk = sqlsrv_query($conn, $sqlEnsure); if ($ensureOk === false) { $err = sqlsrv_errors(); echo json_encode(['success' => false, 'message' => 'Error al preparar tabla de solicitudes', 'detail' => $err]); return; } // Determinar columnas legacy (id_*) y nuevas (*_id) disponibles $has_id_ped = false; $has_id_fac = false; $has_id_usr = false; $chkCols = sqlsrv_query($conn, "SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('dbo.mve_solicitudes') AND name IN ('id_pedimento','id_factura','id_usuario','pedimento_id','factura_id','usuario_id')"); if ($chkCols) { while ($c = sqlsrv_fetch_array($chkCols, SQLSRV_FETCH_ASSOC)) { if ($c['name'] === 'id_pedimento') $has_id_ped = true; if ($c['name'] === 'id_factura') $has_id_fac = true; if ($c['name'] === 'id_usuario') $has_id_usr = true; } sqlsrv_free_stmt($chkCols); } // Validar firma obligatoria if (!$firma_base64 || trim($firma_base64) === '') { echo json_encode(['success' => false, 'message' => 'La firma es obligatoria']); return; } // Construir INSERT dinámico para soportar ambos esquemas $cols = []; $vals = []; $paramsIns = []; // IDs $cols[] = 'pedimento_id'; $vals[] = '?'; $paramsIns[] = $pedimento_id; if ($has_id_ped) { $cols[] = 'id_pedimento'; $vals[] = '?'; $paramsIns[] = $pedimento_id; } $cols[] = 'factura_id'; $vals[] = '?'; $paramsIns[] = $factura_id; if ($has_id_fac) { $cols[] = 'id_factura'; $vals[] = '?'; $paramsIns[] = $factura_id; } $cols[] = 'usuario_id'; $vals[] = '?'; $paramsIns[] = $usuario_id; if ($has_id_usr) { $cols[] = 'id_usuario'; $vals[] = '?'; $paramsIns[] = $usuario_id; } // Resto de columnas $cols = array_merge($cols, ['acepto_declaracion','rfc_importador','ip','firma_base64','firmante']); $vals = array_merge($vals, array_fill(0, 5, '?')); $paramsIns = array_merge($paramsIns, [1, $rfc_importador, $ip, $firma_base64, $firmante]); $sqlIns = 'INSERT INTO mve_solicitudes (' . implode(',', $cols) . ') VALUES (' . implode(',', $vals) . ')'; $ins = sqlsrv_query($conn, $sqlIns, $paramsIns); if ($ins === false) { $err = sqlsrv_errors(); $msg = 'No se pudo registrar la solicitud'; if ($err && isset($err[0]['message'])) { $msg .= ': ' . $err[0]['message']; } echo json_encode(['success' => false, 'message' => $msg]); return; } // Actualizar estado en cove_respuestas a 'solicitado' $sel = sqlsrv_query($conn, "SELECT id FROM cove_respuestas WHERE factura_id = ? AND usuario_id = ?", [$factura_id, $usuario_id]); $row = $sel ? sqlsrv_fetch_array($sel, SQLSRV_FETCH_ASSOC) : null; if ($sel) sqlsrv_free_stmt($sel); if ($row) { sqlsrv_query($conn, "UPDATE cove_respuestas SET estado = 'solicitado', fecha_actualizacion = SYSDATETIME() WHERE id = ?", [$row['id']]); } else { sqlsrv_query($conn, "INSERT INTO cove_respuestas (usuario_id, pedimento_id, factura_id, estado, fecha_actualizacion) VALUES (?, ?, ?, 'solicitado', SYSDATETIME())", [$usuario_id, $pedimento_id, $factura_id]); } // Generar documentos de prueba (acuse y detalle) en el expediente del pedimento $usuario_nombre = $_SESSION['usuario_nombre'] ?? 'sistema'; mve_generar_documentos_expediente($conn, $pedimento_id, $usuario_nombre); echo json_encode(['success' => true]); }