false, 'status' => 'error', 'message' => 'No se recibieron datos para imprimir o formato incorrecto', 'received' => isset($_POST["dataPrint"]) ? substr(print_r($_POST["dataPrint"], true), 0, 200) : 'nada' ]); exit; } try { // Nombre de la impresora de caja $nombreImpresora = isset($dataPrint['printer']) ? $dataPrint['printer'] : "POS-80C"; $connector = new WindowsPrintConnector($nombreImpresora); $printer = new Printer($connector); // ENCABEZADO $printer->setJustification(Printer::JUSTIFY_CENTER); $printer->setTextSize(2, 2); $nombreEmpresa = isset($dataPrint['nombre_empresa']) ? $dataPrint['nombre_empresa'] : (isset($dataPrint['empresa_nombre']) ? $dataPrint['empresa_nombre'] : 'EMPRESA'); $printer->text($nombreEmpresa . "\n"); $printer->setTextSize(1, 1); $direccion = isset($dataPrint['direcion_empresa']) ? $dataPrint['direcion_empresa'] : (isset($dataPrint['empresa_direccion']) ? $dataPrint['empresa_direccion'] : ''); if (!empty($direccion)) { $printer->text($direccion . "\n"); } $printer->text(str_repeat("=", 48) . "\n"); $printer->setEmphasis(true); $printer->text("R E C I B O\n"); $printer->setEmphasis(false); $printer->text(str_repeat("=", 48) . "\n"); // INFORMACIÓN DEL RECIBO $printer->setJustification(Printer::JUSTIFY_LEFT); $fecha = isset($dataPrint['fecha']) ? $dataPrint['fecha'] : date('d-m-Y H:i:s'); $printer->setEmphasis(true); $printer->text("Fecha: "); $printer->setEmphasis(false); $printer->text($fecha . "\n"); /* if (!empty($dataPrint['referencia'])) { $printer->setEmphasis(true); $printer->text("Referencia: "); $printer->setEmphasis(false); $printer->text($dataPrint['referencia'] . "\n"); }*/ if (!empty($dataPrint['cliente'])) { $printer->setEmphasis(true); $printer->text("Cliente: "); $printer->setEmphasis(false); $printer->text($dataPrint['cliente'] . "\n"); } /* if (!empty($dataPrint['caja'])) { $printer->setEmphasis(true); $printer->text("Caja: "); $printer->setEmphasis(false); $printer->text($dataPrint['caja'] . "\n"); }*/ $printer->text(str_repeat("-", 48) . "\n"); // ENCABEZADO DE TABLA $printer->setEmphasis(true); $printer->text("CANT DESCRIPCION TOTAL\n"); $printer->setEmphasis(false); $printer->text(str_repeat("-", 48) . "\n"); // PRODUCTOS $subtotal = 0; if (isset($dataPrint['productos_normal']) && is_array($dataPrint['productos_normal'])) { foreach ($dataPrint['productos_normal'] as $producto) { // Convertir objeto a array si es necesario $productoArray = is_object($producto) ? (array)$producto : $producto; $cant = isset($productoArray['cant']) ? number_format($productoArray['cant'], 0) : '0'; $desc = isset($productoArray['desc']) ? $productoArray['desc'] : ''; $costo = isset($productoArray['costo']) ? floatval($productoArray['costo']) : 0; $cantNum = isset($productoArray['cant']) ? floatval($productoArray['cant']) : 0; $total = $cantNum * $costo; $subtotal += $total; // Línea del producto - cant y descripción $cantTexto = $cant . "x"; $descCorto = substr($desc, 0, 25); $totalStr = "$" . number_format($total, 2); $printer->text(str_pad($cantTexto, 5) . " " . str_pad($descCorto, 36) . str_pad($totalStr, 1, " ", STR_PAD_LEFT) . "\n"); } } $printer->text(str_repeat("=", 48) . "\n"); // TOTALES $printer->setJustification(Printer::JUSTIFY_RIGHT); $totales = isset($dataPrint['totales']) && is_array($dataPrint['totales']) ? $dataPrint['totales'] : []; // Función helper para limpiar valores numéricos $limpiarNumero = function($valor) { if(is_numeric($valor)) return floatval($valor); if(is_string($valor)) return floatval(str_replace(',', '', $valor)); return 0; }; $descuento = $limpiarNumero(isset($totales['descuento']) ? $totales['descuento'] : 0); $propina = $limpiarNumero(isset($totales['propina']) ? $totales['propina'] : 0); $totalTotal = $limpiarNumero(isset($totales['totalTotal']) ? $totales['totalTotal'] : 0); $efectivo = $limpiarNumero(isset($dataPrint['efectivo']) ? $dataPrint['efectivo'] : 0); $pos = $limpiarNumero(isset($dataPrint['pos']) ? $dataPrint['pos'] : 0); $cambio = $limpiarNumero(isset($dataPrint['cambio']) ? $dataPrint['cambio'] : 0); // TOTAL (PRIMERO) $printer->setEmphasis(true); $printer->setTextSize(2, 1); $printer->text("TOTAL: $" . number_format($totalTotal, 2) . "\n"); $printer->setTextSize(1, 1); $printer->setEmphasis(false); // DESCUENTO if ($descuento > 0) { $printer->text("Descuento: -$" . number_format($descuento, 2) . "\n"); } // PROPINA if ($propina > 0) { $printer->text("Propina: $" . number_format($propina, 2) . "\n"); } // MÉTODO DE PAGO if ($efectivo > 0) { $printer->text("Efectivo: $" . number_format($efectivo, 2) . "\n"); } if ($pos > 0) { $printer->text("POS/Tarjeta: $" . number_format($pos, 2) . "\n"); } // CAMBIO (SIEMPRE MOSTRAR) $printer->text("Cambio: $" . number_format($cambio, 2) . "\n"); $printer->text(str_repeat("=", 48) . "\n"); // MENSAJE FINAL $printer->setJustification(Printer::JUSTIFY_CENTER); if (!empty($dataPrint['mensaje_ticket'])) { $printer->text($dataPrint['mensaje_ticket'] . "\n"); } $printer->text("\n¡Gracias por su compra!\n"); $printer->text("Este es un recibo, NO factura\n"); $printer->feed(3); $printer->cut(); $printer->close(); echo json_encode([ 'success' => true, 'status' => 'success', 'message' => 'Recibo impreso correctamente en ' . $nombreImpresora ]); } catch (Exception $e) { echo json_encode([ 'success' => false, 'status' => 'error', 'message' => 'Error al imprimir: ' . $e->getMessage() ]); } ?>