- Mejora en el manejo de errores - Optimización de la configuración de DOMPDF - Corrección de problemas de rendimiento - Mejora en la generación de PDF
666 lines
22 KiB
PHP
Executable File
666 lines
22 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Generación de acuse de recibo con DOMPDF
|
|
*
|
|
* Este archivo genera un PDF de acuse de recibo para órdenes de compra.
|
|
* Utiliza DOMPDF para la generación de PDFs con manejo de errores mejorado.
|
|
*/
|
|
|
|
// Usar DOMPDF
|
|
use Dompdf\Dompdf;
|
|
use Dompdf\Options;
|
|
|
|
// Configuración de manejo de errores
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 0);
|
|
ini_set('log_errors', 1);
|
|
ini_set('error_log', '/var/www/html/ventas/logs/php_errors.log');
|
|
ini_set('max_execution_time', 300); // 5 minutos para generación de PDF
|
|
ini_set('memory_limit', '512M'); // 512MB de memoria
|
|
|
|
// Definir constantes para rutas
|
|
define('TEMP_DIR', sys_get_temp_dir() . '/dompdf_');
|
|
@mkdir(TEMP_DIR, 0755, true);
|
|
|
|
// Función para manejar errores fatales
|
|
register_shutdown_function(function() {
|
|
$error = error_get_last();
|
|
if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
|
|
$message = sprintf(
|
|
"[%s] Error fatal (%s): %s en %s línea %s\nStack trace:\n%s",
|
|
date('Y-m-d H:i:s'),
|
|
$error['type'],
|
|
$error['message'],
|
|
$error['file'],
|
|
$error['line'],
|
|
json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), JSON_PRETTY_PRINT)
|
|
);
|
|
error_log($message);
|
|
|
|
if (!headers_sent()) {
|
|
http_response_code(500);
|
|
header('Content-Type: text/plain; charset=utf-8');
|
|
}
|
|
echo "Ha ocurrido un error inesperado. Por favor, intente nuevamente más tarde.\n";
|
|
}
|
|
});
|
|
|
|
// Función para manejar excepciones no capturadas
|
|
set_exception_handler(function($exception) {
|
|
$message = sprintf(
|
|
"[%s] Excepción no capturada: %s en %s línea %s\nStack trace:\n%s",
|
|
date('Y-m-d H:i:s'),
|
|
$exception->getMessage(),
|
|
$exception->getFile(),
|
|
$exception->getLine(),
|
|
$exception->getTraceAsString()
|
|
);
|
|
error_log($message);
|
|
|
|
if (!headers_sent()) {
|
|
http_response_code(500);
|
|
header('Content-Type: text/plain; charset=utf-8');
|
|
}
|
|
echo "Ha ocurrido un error inesperado. Por favor, intente nuevamente más tarde.\n";
|
|
exit(1);
|
|
});
|
|
|
|
// Función para manejar errores
|
|
set_error_handler(function($errno, $errstr, $errfile, $errline) {
|
|
// No manejar errores que estén enmascarados con @
|
|
if (error_reporting() === 0) {
|
|
return false;
|
|
}
|
|
|
|
$message = sprintf(
|
|
"[%s] Error (%s): %s en %s línea %s\nStack trace:\n%s",
|
|
date('Y-m-d H:i:s'),
|
|
$errno,
|
|
$errstr,
|
|
$errfile,
|
|
$errline,
|
|
json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), JSON_PRETTY_PRINT)
|
|
);
|
|
error_log($message);
|
|
|
|
// No ejecutar el gestor de errores interno de PHP
|
|
return true;
|
|
});
|
|
|
|
try {
|
|
// Validar autenticación
|
|
if (!isset($empresa) || !method_exists($empresa, 'AuthUser')) {
|
|
throw new Exception('Error de autenticación: Objeto empresa no válido');
|
|
}
|
|
$empresa->AuthUser();
|
|
|
|
// Cargar el autoloader de Composer
|
|
$autoloadPath = DOC_ROOT . '/vendor/autoload.php';
|
|
if (!file_exists($autoloadPath)) {
|
|
throw new Exception('No se encontró el archivo autoload.php de Composer');
|
|
}
|
|
require_once $autoloadPath;
|
|
|
|
// Inicializar variables
|
|
$subtotales = [];
|
|
$html = '';
|
|
$impBrutoG = 0.0;
|
|
$impNetoG = 0.0;
|
|
$cantTotal = 0.0;
|
|
$descGlobal = 0.0;
|
|
$totalGlobal = 0.0;
|
|
$porcDesc = 0.0;
|
|
$infS = [];
|
|
$porcDesc = 0; // Inicializar variable faltante
|
|
|
|
$pedidoId = $_GET['pedidoId'];
|
|
|
|
$pedido->setPedidoId($pedidoId);
|
|
$info = $pedido->Info();
|
|
|
|
$rfc->setRfcId(1);
|
|
$infE = $util->EncodeRow($rfc->Info());
|
|
|
|
$direccion = $infE['calle'];
|
|
|
|
if($infE['noExt'] != '')
|
|
$direccion .= ' No. Ext. '.$infE['noExt'];
|
|
if($infE['noInt'] != '')
|
|
$direccion .= ', No. Int. '.$infE['noInt'];
|
|
if($infE['colonia'] != '')
|
|
$direccion .= ', Col. '.$infE['colonia'];
|
|
// if($infE['localidad'] != '')
|
|
// $direccion .= ', '.$infE['localidad'];
|
|
// if($infE['ciudad'] != '')
|
|
// $direccion .= ', '.$infE['ciudad'];
|
|
if($infE['municipio'] != '')
|
|
$direccion .= ', '.$infE['municipio'];
|
|
if($infE['estado'] != '')
|
|
$direccion .= ', '.$infE['estado'];
|
|
if(isset($infE['codigoPostal']) && $infE['codigoPostal'] != '')
|
|
$direccion .= 'C.P. '.$infE['codigoPostal'];
|
|
|
|
$infE['direccion'] = $direccion;
|
|
|
|
$proveedor->setProveedorId($info['proveedorId']);
|
|
$infPv = $util->EncodeRow($proveedor->Info());
|
|
|
|
$fecha = date('d-m-Y',strtotime($info['fecha']));
|
|
$info['fecha'] = $fecha;
|
|
|
|
$fechaEntrega = date('d-m-Y',strtotime($info['fechaEntrega']));
|
|
$info['fechaEntrega'] = $fechaEntrega;
|
|
|
|
/*
|
|
if($info['metodoCompra'] == 'conIva')
|
|
$info['metodoCompra'] = 'IVA Incluido';
|
|
else
|
|
$info['metodoCompra'] = 'IVA No Incluido';
|
|
*/
|
|
//Productos
|
|
|
|
$resProducts = $pedido->GetProductos();
|
|
|
|
$sugerencias = 0;
|
|
$subtotalP = 0;
|
|
$products = array();
|
|
foreach($resProducts as $card){
|
|
|
|
$prodCatId = $card['prodCatId'];
|
|
$prodSubcatId = $card['prodSubcatId'];
|
|
$productoId = $card['productoId'];
|
|
|
|
$card['productoId'] = $productoId;
|
|
$card['prodCatId'] = $prodCatId;
|
|
$card['prodSubcatId'] = $prodSubcatId;
|
|
|
|
$prodCat->setProdCatId($prodCatId);
|
|
$card['departamento'] = $prodCat->GetNameById();
|
|
|
|
$prodSubcat->setProdSubcatId($prodSubcatId);
|
|
$card['linea'] = $prodSubcat->GetNameById();
|
|
|
|
$producto->setProductoId($productoId);
|
|
$infP = $producto->Info();
|
|
$card['modelo'] = $infP['modelo'];
|
|
$card['imagen'] = $infP['imagen'];
|
|
$card['codigoBarra'] = $infP['codigoBarra'];
|
|
|
|
$card['atributos'] = $producto->GetAtributosAll();
|
|
|
|
if($card['prendasComp'] == 1)
|
|
$card['cantidad'] = $card['totalLote'] * $card['cantLotes'];
|
|
else
|
|
$card['cantidad'] = $card['prendasRec'];
|
|
|
|
$totalP = $card['costo'] * $card['cantidad'];
|
|
$card['total'] = number_format($totalP,2,'.','');
|
|
|
|
$subtotalP += $totalP;
|
|
|
|
$card['subtotales'] = isset($subtotales) ? $subtotales : array();
|
|
|
|
$products[] = $card;
|
|
|
|
}//foreach
|
|
|
|
if($info['fechaFolio'] == "0000-00-00")
|
|
{
|
|
$fechaP = "---";
|
|
}
|
|
else
|
|
{
|
|
$fechaP = date('d-m-Y',strtotime($info['fechaFolio']));
|
|
}
|
|
|
|
if($info['fechaOrdenCompIng'] == "0000-00-00")
|
|
{
|
|
$fechaP1 = "---";
|
|
}
|
|
else
|
|
{
|
|
$fechaP1 = date('d-m-Y',strtotime($info['fechaOrdenCompIng']));
|
|
}
|
|
|
|
if($info['fechaOrdenCompIng'] == "0000-00-00")
|
|
{
|
|
$horaP1 = "---";
|
|
}
|
|
else
|
|
{
|
|
$horaP1 = date('H:i:s',strtotime($info['fechaOrdenCompIng']));
|
|
}
|
|
|
|
if($fechaP1 == "---")
|
|
{
|
|
$fechaV = "---";
|
|
}
|
|
else
|
|
{
|
|
$fechaV = date('d-m-Y',strtotime($fechaP1.' + 90 days'));
|
|
}
|
|
|
|
$porcDesc = $info['porcPub'] + $info['porcFlete'] + $info['porcDes'] + $info['porcEsp'];
|
|
|
|
$foliosP = array();
|
|
if($info['folioProv'])
|
|
$foliosP[] = $info['folioProv'];
|
|
if($info['folioProv2'])
|
|
$foliosP[] = $info['folioProv2'];
|
|
if($info['folioProv3'])
|
|
$foliosP[] = $info['folioProv3'];
|
|
if($info['folioProv4'])
|
|
$foliosP[] = $info['folioProv4'];
|
|
if($info['folioProv5'])
|
|
$foliosP[] = $info['folioProv5'];
|
|
|
|
$foliosProv = implode('<br>',$foliosP);
|
|
|
|
//HTML - PDF
|
|
|
|
// Inicializar la variable $html
|
|
$html = '';
|
|
|
|
// Construir el HTML
|
|
$html .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
$html .= '<html xmlns="http://www.w3.org/1999/xhtml">';
|
|
$html .= '<head>';
|
|
$html .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
|
|
$html .= '<style type="text/css">';
|
|
$html .= 'body {';
|
|
$html .= ' font-family: Verdana, Arial, Helvetica, sans-serif;';
|
|
$html .= ' font-size: 10px;';
|
|
$html .= ' margin: 0;';
|
|
$html .= ' padding: 10px;';
|
|
$html .= '}';
|
|
$html .= '.titulo {';
|
|
$html .= ' color: #FFFFFF;';
|
|
$html .= ' font-weight: bold;';
|
|
$html .= ' font-size: 11px;';
|
|
$html .= ' background-color: #809829;';
|
|
$html .= ' text-align: center;';
|
|
$html .= ' padding: 3px;';
|
|
$html .= ' margin-bottom: 5px;';
|
|
$html .= '}';
|
|
$html .= 'table {';
|
|
$html .= ' width: 100%;';
|
|
$html .= ' border-collapse: collapse;';
|
|
$html .= ' margin-bottom: 5px;';
|
|
$html .= ' border: 1px solid #000000;';
|
|
$html .= '}';
|
|
$html .= 'td, th {';
|
|
$html .= ' padding: 2px;';
|
|
$html .= ' border: 1px solid #000000;';
|
|
$html .= ' font-size: 10px;';
|
|
$html .= ' vertical-align: top;';
|
|
$html .= '}';
|
|
$html .= '</style>';
|
|
$html .= '</head>';
|
|
$html .= '<body>';
|
|
$html .= '<div style="width: 100%; max-width: 800px; margin: 0 auto;">';
|
|
|
|
// Asegurarse de que los valores numéricos estén formateados correctamente
|
|
$impBrutoG = (float)$impBrutoG;
|
|
$impNetoG = (float)$impNetoG;
|
|
$porcDesc = (float)$porcDesc;
|
|
|
|
$html .= '<table border="0" cellpadding="0" cellspacing="0">';
|
|
$html .= '<tr>';
|
|
$html .= '<td width="430" style="padding: 5px;">';
|
|
$html .= '<b>CEDIS <br>';
|
|
$html .= 'COMERCIALIZADORA NOVOMODA, S.A. DE C.V.</b><br />';
|
|
$html .= htmlspecialchars($infE['direccion'], ENT_QUOTES, 'UTF-8');
|
|
$html .= '</td>';
|
|
$html .= '<td></td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
|
|
$html .= '<br>';
|
|
|
|
$html .= '<table border="1" cellspacing="0" cellpadding="0" width="100%">';
|
|
$html .= '<tr>';
|
|
$html .= '<td align="center"><b>ORDEN COMPRA</b></td>';
|
|
$html .= '<td width="12%" align="center"><b>FECHA EXP.</b></td>';
|
|
$html .= '<td width="12%" align="center"><b>CONDICIONES</b></td>';
|
|
$html .= '<td width="12%" align="center"><b>FECHA VECTO.</b></td>';
|
|
$html .= '<td width="12%" align="center"><b>FACT/REM.</b></td>';
|
|
$html .= '<td width="12%" align="center"><b>FECHA REG.</b></td>';
|
|
$html .= '<td width="12%" align="center"><b>HORA REG.</b></td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td align="center">' . htmlspecialchars($info['noPedido'], ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '<td align="center">' . htmlspecialchars($fechaP, ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '<td align="center">90 Dias</td>';
|
|
$html .= '<td align="center">' . htmlspecialchars($fechaV, ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '<td align="center">' . htmlspecialchars($foliosProv, ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '<td align="center">' . htmlspecialchars($fechaP, ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '<td align="center">' . htmlspecialchars($horaP1, ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td align="center"><b>NO. PROV.</b></td>';
|
|
$html .= '<td align="center"><b>T. MONEDA.</b></td>';
|
|
$html .= '<td align="center"><b>CONC. INV.</b></td>';
|
|
$html .= '<td align="center"><b>CONC. CXP.</b></td>';
|
|
$html .= '<td align="center"></td>';
|
|
$html .= '<td align="center"></td>';
|
|
$html .= '<td align="center"></td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td align="center">' . htmlspecialchars($info['proveedorId'], ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '<td align="center">MONEDA NACIONAL</td>';
|
|
$html .= '<td align="center">ENT X COMPR</td>';
|
|
$html .= '<td align="center">COMPRAS</td>';
|
|
$html .= '<td align="center"> --- </td>';
|
|
$html .= '<td align="center"> --- </td>';
|
|
$html .= '<td align="center"> --- </td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
|
|
//DATOS DEL PROVEEDOR
|
|
|
|
$html .= '<br><table border="0" cellspacing="0" cellpadding="0">';
|
|
$html .= '<tr>';
|
|
$html .= '<td colspan="4" class="titulo">DATOS DEL PROVEEDOR</td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td width="23%" style="padding:2px;"><b>Razón Social</b></td>';
|
|
$html .= '<td width="27%"><b>Calle</b></td>';
|
|
$html .= '<td>' . htmlspecialchars($infPv['calle'], ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td style="padding:2px;"><b>RFC</b></td>';
|
|
$html .= '<td>' . htmlspecialchars($infPv['rfc'], ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '<td><b>Colonia</b></td>';
|
|
$html .= '<td>' . htmlspecialchars($infPv['colonia'], ENT_QUOTES, 'UTF-8') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '<td style="padding:2px;"><b>Teléfonos</b></td>';
|
|
$html .= '<td>' . (isset($infPv['phone']) ? htmlspecialchars($infPv['phone'], ENT_QUOTES, 'UTF-8') : '') . '</td>';
|
|
$html .= '<td><b>Delegación o Municipio</b></td>';
|
|
$html .= '<td>' . (isset($infPv['municipio']) ? htmlspecialchars($infPv['municipio'], ENT_QUOTES, 'UTF-8') : '') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td style="padding:2px;"><b>C.P.</b></td>';
|
|
$html .= '<td>' . (isset($infS['codigoPostal']) ? htmlspecialchars($infS['codigoPostal'], ENT_QUOTES, 'UTF-8') : '') . '</td>';
|
|
$html .= '<td><b>Estado</b></td>';
|
|
$html .= '<td>' . (isset($infS['estado']) ? htmlspecialchars($infS['estado'], ENT_QUOTES, 'UTF-8') : '') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
|
|
//PRODUCTOS
|
|
|
|
$html .= '<br><table border="0" cellspacing="0" cellpadding="0">';
|
|
$html .= '<tr>';
|
|
$html .= '<td class="titulo">PRODUCTOS</td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
$html .= '<br>';
|
|
|
|
$html .= '<table border="1" cellspacing="0" cellpadding="0" width="100%">';
|
|
$html .= '<tr>';
|
|
$html .= '<td align="center" bgcolor="#CCCCCC">DESCRIPCION</td>';
|
|
$html .= '<td width="10%" align="center" bgcolor="#CCCCCC">T.U.</td>';
|
|
$html .= '<td width="10%" align="center" bgcolor="#CCCCCC">CANTIDAD</td>';
|
|
$html .= '<td width="10%" align="center" bgcolor="#CCCCCC">PRECIO</td>';
|
|
$html .= '<td width="10%" align="center" bgcolor="#CCCCCC">DESC.</td>';
|
|
$html .= '<td width="10%" align="center" bgcolor="#CCCCCC">IMP. BRUTO</td>';
|
|
$html .= '<td width="10%" align="center" bgcolor="#CCCCCC">IMP. NETO</td>';
|
|
$html .= '</tr>';
|
|
|
|
$cantTotal = 0;
|
|
$totalGlobal = 0;
|
|
$descGlobal = 0;
|
|
|
|
foreach($products as $res) {
|
|
// Asegurar que todos los valores sean numéricos
|
|
$impBruto = isset($res['total']) ? (float)$res['total'] : 0.0;
|
|
$porcDesc = isset($porcDesc) ? (float)$porcDesc : 0.0;
|
|
$totalDesc = $impBruto * ($porcDesc / 100);
|
|
$descGlobal = (float)$descGlobal + $totalDesc;
|
|
$impNeto = $impBruto - $totalDesc;
|
|
$totalGlobal = (float)$totalGlobal + $impNeto;
|
|
|
|
$html .= '<tr>';
|
|
$html .= '<td>' . (isset($res['codigoBarras']) ? htmlspecialchars($res['codigoBarras'], ENT_QUOTES, 'UTF-8') : '') . '</td>';
|
|
$html .= '<td>' . (isset($res['nombre']) ? htmlspecialchars($res['nombre'], ENT_QUOTES, 'UTF-8') : '') . '</td>';
|
|
$html .= '<td align="center">' . (isset($res['unidad']) ? htmlspecialchars($res['unidad'], ENT_QUOTES, 'UTF-8') : '') . '</td>';
|
|
$html .= '<td align="center">' . (isset($res['cantidad']) ? number_format((float)$res['cantidad'], 2, '.', '') : '0.00') . '</td>';
|
|
$html .= '<td align="right">$ ' . (isset($res['precio']) ? number_format((float)$res['precio'], 2, '.', ',') : '0.00') . '</td>';
|
|
$html .= '<td align="right">$ ' . number_format($totalDesc, 2, '.', ',') . '</td>';
|
|
$html .= '<td align="right">$ ' . number_format($impBruto, 2, '.', ',') . '</td>';
|
|
$html .= '<td align="right">$ ' . number_format($impNeto, 2, '.', ',') . '</td>';
|
|
$cantTotal = (float)$cantTotal + (isset($res['cantidad']) ? (float)$res['cantidad'] : 0.0);
|
|
$impBrutoG = (float)$impBrutoG + $impBruto;
|
|
$impNetoG = (float)$impNetoG + $impNeto;
|
|
}
|
|
|
|
// Agregar fila de totales
|
|
$html .= '<tr>';
|
|
$html .= '<td align="center"></td>';
|
|
$html .= '<td align="center"></td>';
|
|
$html .= '<td align="center">TOTALES</td>';
|
|
$html .= '<td align="center">' . number_format($cantTotal, 0) . '</td>';
|
|
$html .= '<td align="center"></td>';
|
|
$html .= '<td align="center"></td>';
|
|
$html .= '<td align="right">$' . number_format($impNetoG, 2) . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
|
|
//TOTALES
|
|
|
|
if(isset($info['subtotal2']) && $info['subtotal2'] > 0){
|
|
$info['subtotal'] = $info['subtotal2'];
|
|
$info['iva'] = $info['iva2'];
|
|
$info['total'] = $info['total2'];
|
|
}
|
|
|
|
$ivaPorc = 16;
|
|
|
|
if($porcDesc > 0){
|
|
// Asegurar que los valores sean numéricos
|
|
$total = isset($info['total']) ? (float)$info['total'] : 0.0;
|
|
$ivaPorc = 16.0;
|
|
$info['subtotal'] = $total / (1 + ($ivaPorc/100));
|
|
$info['iva'] = $info['subtotal'] * ($ivaPorc/100);
|
|
}
|
|
|
|
// Tabla de totales
|
|
$html .= '<br><table border="0" cellspacing="0" cellpadding="0" width="100%">';
|
|
$html .= '<tr>';
|
|
$html .= '<td width="100%" align="right">';
|
|
$html .= '<table border="0" cellspacing="0" cellpadding="0">';
|
|
$html .= '<tr>';
|
|
$html .= '<td width="100" align="right"><b>SUBTOTAL:</b></td>';
|
|
$html .= '<td width="100" align="right">$ ' . number_format((float)$info['subtotal'], 2, '.', ',') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td align="right"><b>IVA (16%):</b></td>';
|
|
$html .= '<td align="right">$ ' . number_format((float)$info['iva'], 2, '.', ',') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '<tr>';
|
|
$html .= '<td align="right"><b>TOTAL:</b></td>';
|
|
$html .= '<td align="right">$ ' . number_format((float)$info['total'], 2, '.', ',') . '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
$html .= '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
|
|
// Firmas
|
|
$html .= '<br><br><br><table border="0" cellspacing="0" cellpadding="0" width="100%">';
|
|
$html .= '<tr>';
|
|
$html .= '<td width="33%" align="center">';
|
|
$html .= '________________________________<br>';
|
|
$html .= '<b>NOMBRE Y FIRMA DE QUIEN RECIBE</b>';
|
|
$html .= '</td>';
|
|
$html .= '<td width="33%" align="center">';
|
|
$html .= '________________________________<br>';
|
|
$html .= '<b>NOMBRE Y FIRMA DE QUIEN AUTORIZA</b>';
|
|
$html .= '</td>';
|
|
$html .= '<td width="33%" align="center">';
|
|
$html .= '________________________________<br>';
|
|
$html .= '<b>NOMBRE Y FIRMA DE QUIEN ENTREGA</b>';
|
|
$html .= '</td>';
|
|
$html .= '</tr>';
|
|
$html .= '</table>';
|
|
|
|
$html .= '<br><table border="0" cellspacing="0" cellpadding="0">';
|
|
$html .= '<tr>';
|
|
$html .= '<td class="titulo">TOTALES</td>';
|
|
$html .= '</tr>
|
|
</table>
|
|
<table border="0" cellspacing="0" cellpadding="0">';
|
|
$html .= '<tr>';
|
|
$html .= '<td width="60%"></td>';
|
|
$html .= '<td width="20%" valign="top" style="padding: 5px;">';
|
|
|
|
if($porcDesc > 0)
|
|
$html .= '<b>DESCUENTO</b> <br>';
|
|
|
|
if($info['metodoCompra'] == 'conIva')
|
|
$html .= '<b>SUBTOTAL</b> <br>
|
|
<b>IVA '.$ivaPorc.'%</b> <br>';
|
|
|
|
$html .= '<b>TOTAL</b>';
|
|
|
|
|
|
$html .= '</td>
|
|
<td width="20%" align="right" valign="top" style="padding: 5px;">';
|
|
|
|
if($porcDesc > 0)
|
|
$html .= '$'.number_format($descGlobal,2).'<br>';
|
|
|
|
if($info['metodoCompra'] == 'conIva')
|
|
$html .= '$'.$info['subtotal'].'<br>
|
|
$'.$info['iva'].'<br>';
|
|
|
|
$html .= number_format((float)$info['total'], 2, '.', ',');
|
|
$html .= '</td>';
|
|
$html .= '</tr>';
|
|
|
|
// Inicializar DOMPDF con configuración optimizada
|
|
try {
|
|
$options = new Options([
|
|
'isRemoteEnabled' => true,
|
|
'isHtml5ParserEnabled' => true,
|
|
'isPhpEnabled' => true,
|
|
'isJavascriptEnabled' => false,
|
|
'defaultFont' => 'Arial',
|
|
'tempDir' => TEMP_DIR,
|
|
'fontCache' => TEMP_DIR,
|
|
'chroot' => realpath('.'),
|
|
'debugPng' => false,
|
|
'debugKeepTemp' => false,
|
|
'debugCss' => false,
|
|
'debugLayout' => false,
|
|
'enable_font_subsetting' => true,
|
|
'isFontSubsettingEnabled' => true,
|
|
'dpi' => 96
|
|
]);
|
|
|
|
$dompdf = new Dompdf($options);
|
|
$dompdf->setPaper('letter', 'portrait');
|
|
|
|
// Cargar el HTML con manejo de errores
|
|
$dompdf->loadHtml($html, 'UTF-8');
|
|
|
|
// Renderizar el PDF
|
|
$dompdf->render();
|
|
} catch (Exception $e) {
|
|
error_log('Error al generar el PDF: ' . $e->getMessage());
|
|
throw new Exception('Error al generar el PDF. Por favor, verifica el formato del contenido.');
|
|
}
|
|
|
|
// Limpiar buffer de salida
|
|
while (ob_get_level() > 0) {
|
|
if (!@ob_end_clean()) {
|
|
error_log('No se pudo limpiar el buffer de salida');
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Configurar encabezados para mostrar el PDF
|
|
$filename = 'acuse_recibo_' . $pedidoId . '_' . date('Y-m-d') . '.pdf';
|
|
|
|
// Forzar la codificación UTF-8 en los encabezos
|
|
$filename_encoded = rawurlencode($filename);
|
|
$filename_utf8 = str_replace(['+', '%20'], ' ', $filename_encoded);
|
|
|
|
// Configurar encabezados con manejo de caché
|
|
header('Content-Type: application/pdf');
|
|
header('Content-Disposition: inline; filename="' . $filename_utf8 . '"; filename*=UTF-8\'\'' . $filename_encoded);
|
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
header('Pragma: public');
|
|
header('Expires: 0');
|
|
header('Content-Transfer-Encoding: binary');
|
|
header('Accept-Ranges: bytes');
|
|
|
|
// Enviar el PDF al navegador
|
|
$output = $dompdf->output();
|
|
if ($output === false) {
|
|
throw new Exception('Error al generar el contenido del PDF');
|
|
}
|
|
|
|
// Liberar memoria
|
|
unset($dompdf);
|
|
|
|
// Limpiar cualquier salida no deseada
|
|
if (ob_get_level() > 0) {
|
|
ob_clean();
|
|
}
|
|
|
|
// Enviar el PDF
|
|
echo $output;
|
|
|
|
// Limpiar la salida y terminar
|
|
if (function_exists('fastcgi_finish_request')) {
|
|
fastcgi_finish_request();
|
|
}
|
|
|
|
// Limpiar memoria
|
|
gc_collect_cycles();
|
|
exit(0);
|
|
} catch (Exception $e) {
|
|
// Registrar el error en el archivo de log con más contexto
|
|
$errorDetails = [
|
|
'message' => $e->getMessage(),
|
|
'file' => $e->getFile(),
|
|
'line' => $e->getLine(),
|
|
'code' => $e->getCode(),
|
|
'trace' => $e->getTrace(),
|
|
'request' => [
|
|
'uri' => $_SERVER['REQUEST_URI'] ?? null,
|
|
'method' => $_SERVER['REQUEST_METHOD'] ?? null,
|
|
'ip' => $_SERVER['REMOTE_ADDR'] ?? null,
|
|
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
|
|
'referer' => $_SERVER['HTTP_REFERER'] ?? null,
|
|
'query' => $_GET,
|
|
'post' => $_POST
|
|
]
|
|
];
|
|
|
|
error_log('Error en pedidos-acuse.php: ' . json_encode($errorDetails, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
|
|
|
// Limpiar cualquier salida no deseada
|
|
while (ob_get_level() > 0) {
|
|
@ob_end_clean();
|
|
}
|
|
|
|
// Mostrar mensaje de error al usuario
|
|
if (!headers_sent()) {
|
|
header('Content-Type: text/plain; charset=utf-8');
|
|
http_response_code(500);
|
|
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
|
header('Pragma: no-cache');
|
|
}
|
|
|
|
// Mostrar mensaje seguro para el usuario
|
|
if (ini_get('display_errors')) {
|
|
echo 'Error al generar el acuse de recibo: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
|
|
} else {
|
|
echo 'Error al generar el acuse de recibo. Por favor, intente nuevamente más tarde.';
|
|
}
|
|
|
|
// Terminar la ejecución
|
|
exit(1);
|
|
}
|