Autosave: 20260522-025905

This commit is contained in:
Flatlogic Bot 2026-05-22 02:59:06 +00:00
parent 603ef2ccb9
commit 8073e5e1b3
3 changed files with 130 additions and 87 deletions

View File

@ -16,7 +16,7 @@ if (empty($codes)) {
<title>Imprimir Etiquetas Térmicas</title>
<style>
body {
font-family: Verdana, sans-serif;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
@ -41,19 +41,21 @@ if (empty($codes)) {
background: #0056b3;
}
/* Hoja: 96mm x 75mm (Horizontal) */
/* Hoja: 96mm x 75mm */
.etiquetas-container {
width: 96mm;
height: 75mm;
display: grid;
grid-template-columns: repeat(3, 28mm);
grid-template-rows: repeat(3, 21mm);
gap: 2mm;
justify-content: center;
align-content: center;
column-gap: 4mm;
row-gap: 3mm;
padding-left: 2.5mm;
padding-top: 6.5mm; /* Aumentado de 5mm a 6.5mm */
background: white;
box-sizing: border-box;
page-break-after: always;
overflow: hidden;
}
.etiqueta {
@ -62,41 +64,47 @@ if (empty($codes)) {
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: flex-start; /* Cambiado de center a flex-start para controlar el inicio */
justify-content: center;
align-items: center;
overflow: hidden;
text-align: center;
padding: 6mm 1mm 1mm 1mm; /* Regresado a 6mm para que no se corte el texto AFS y suba la posición */
border: 0.1mm solid #eee; /* Guía visual en pantalla */
padding: 0;
border: none;
}
.barcode-container {
height: 11mm;
height: 11.5mm;
display: flex;
justify-content: center;
align-items: center;
margin: 0; /* Eliminado margen para control total con el padding de la etiqueta */
padding: 0 1mm;
margin-top: 1.5mm; /* Añadido margen superior para bajarlo un poco */
padding: 0;
box-sizing: border-box;
width: 100%;
}
.barcode-container svg {
height: 11mm;
height: 11.5mm;
width: auto;
display: block;
margin: 0 auto;
/* Desactivar suavizado para máxima nitidez */
shape-rendering: crispEdges;
}
.sku-text {
font-size: 7px;
margin-top: 1mm; /* Reducido ligeramente */
letter-spacing: 0.5px;
font-family: Arial, sans-serif;
font-size: 3.5mm;
font-weight: normal;
margin-top: 0.5mm;
width: 100%;
line-height: 1;
color: black;
}
@media print {
@page {
size: 96mm 75mm landscape;
size: 96mm 75mm;
margin: 0;
}
body {
@ -112,9 +120,6 @@ if (empty($codes)) {
box-shadow: none;
margin: 0;
}
.etiqueta {
border: none;
}
}
</style>
</head>
@ -137,8 +142,8 @@ if (empty($codes)) {
<div class="etiqueta">
<div class="barcode-container">
<?php
// Usando Code 128 Estándar Universal (Factor 1.0, sin reducción)
echo $generator->getBarcode($code, 1.0, 100, 'black', 0);
// Narrow bar: 0.25mm (2 dots), Height: 11.5mm, Quiet Zone: 4mm
echo $generator->getBarcode($code, 0.25, 11.5, 'black', 4);
?>
</div>
<div class="sku-text"><?php echo htmlspecialchars($code); ?></div>

View File

@ -1,5 +1,5 @@
<?php
// Simplified Barcode Generator for Code 128
// Simplified Barcode Generator for Code 128 and Code 39
// Generates SVG output.
class BarcodeGenerator
@ -11,29 +11,27 @@ class BarcodeGenerator
$this->barcode_codes = $this->getCode128Map();
}
public function getBarcode($code, $widthFactor = 1, $height = 50, $foregroundColor = 'black', $barReduction = 0)
public function getBarcode($code, $narrowBarWidth = 0.25, $height = 11.5, $foregroundColor = 'black', $quietZoneMM = 4, $type = 'C128')
{
$barcodeData = $this->getBarcodeData($code);
$barcodeData = ($type === 'C39') ? $this->getBarcodeData39($code) : $this->getBarcodeData($code);
if (!$barcodeData) return '';
$bars = '';
$quietZone = 10;
$x = $quietZone;
$x = $quietZoneMM;
$barArray = str_split($barcodeData['bars']);
for ($i = 0; $i < count($barArray); $i++) {
$val = (int)$barArray[$i];
$width = $widthFactor * $val;
if ($i % 2 == 0) { // Even indices are bars, odd are spaces
// Apply bar reduction to increase white space between bars
$drawWidth = max(0.4, $width - $barReduction);
$bars .= '<rect x="' . $x . '" y="0" width="' . $drawWidth . '" height="' . $height . '" fill="' . $foregroundColor . '" />';
$width = $narrowBarWidth * $val;
if ($i % 2 == 0) { // Even indices are bars
$bars .= '<rect x="' . $x . '" y="0" width="' . $width . '" height="' . $height . '" fill="' . $foregroundColor . '" />';
}
$x += $width;
}
$totalWidth = $x + $quietZone;
$svg = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="' . $totalWidth . '" height="' . $height . '" viewBox="0 0 ' . $totalWidth . ' ' . $height . '" shape-rendering="crispEdges">';
$totalWidth = $x + $quietZoneMM;
// Using crispEdges for maximum sharpness on thermal printers
$svg = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="' . $totalWidth . 'mm" height="' . $height . 'mm" viewBox="0 0 ' . $totalWidth . ' ' . $height . '" shape-rendering="crispEdges">';
$svg .= '<rect width="' . $totalWidth . '" height="' . $height . '" fill="white" />';
$svg .= $bars;
$svg .= '</svg>';
@ -43,10 +41,9 @@ class BarcodeGenerator
private function getBarcodeData($code)
{
// Remove any accidental spaces and trim
$code = str_replace(' ', '', trim($code));
$code = str_replace(' ', '', strtoupper(trim($code)));
$len = strlen($code);
$indices = [104]; // Start B (Standard Set B)
$indices = [104]; // Start B
for ($i = 0; $i < $len; $i++) {
$char = $code[$i];
@ -56,7 +53,6 @@ class BarcodeGenerator
}
}
// Checksum calculation
$sum = $indices[0];
for ($i = 1; $i < count($indices); $i++) {
$sum += ($indices[$i] * $i);
@ -75,6 +71,33 @@ class BarcodeGenerator
return ['bars' => $bars];
}
private function getBarcodeData39($code)
{
$code = '*' . strtoupper(trim($code)) . '*';
$map = [
'0' => '111221211', '1' => '211211112', '2' => '112211112', '3' => '212211111',
'4' => '111221112', '5' => '211221111', '6' => '112221111', '7' => '111211212',
'8' => '211211211', '9' => '112211211', 'A' => '211112112', 'B' => '112112112',
'C' => '212112111', 'D' => '111122112', 'E' => '211122111', 'F' => '112122111',
'G' => '111112212', 'H' => '211112211', 'I' => '112112211', 'J' => '111122211',
'K' => '211111122', 'L' => '112111122', 'M' => '212111121', 'N' => '111121122',
'O' => '211121121', 'P' => '112121121', 'Q' => '111111222', 'R' => '211111221',
'S' => '112111221', 'T' => '111121221', 'U' => '221111112', 'V' => '122111112',
'W' => '222111111', 'X' => '121121112', 'Y' => '221121111', 'Z' => '122121111',
'-' => '121111212', '.' => '221111211', ' ' => '122111211', '*' => '121121211',
'$' => '121212111', '/' => '121211121', '+' => '121112121', '%' => '111212121'
];
$bars = '';
for ($i = 0; $i < strlen($code); $i++) {
$char = $code[$i];
if (isset($map[$char])) {
$bars .= $map[$char] . '1'; // Add a narrow space between characters
}
}
return ['bars' => rtrim($bars, '1')];
}
private function getCharValue($set, $char)
{
if (isset($this->barcode_codes[$set][$char])) {
@ -107,12 +130,12 @@ class BarcodeGenerator
'212123', '212321', '232121', '111323', '131123', '131321', '112313', '132113', '132311', '211313', // 30-39
'231113', '231311', '112133', '112331', '132131', '113123', '113321', '133121', '313121', '211331', // 40-49
'231131', '213113', '213311', '213131', '311123', '311321', '331121', '312113', '312311', '332111', // 50-59
'314111', '221411', '413111', '111224', '111421', '121124', '121421', '141122', '141221', '112214', // 60-69
'112412', '122114', '122411', '142112', '142211', '241211', '221114', '411122', '411221', '421121', // 70-79
'421211', '212141', '214121', '412121', '111143', '111341', '131141', '114113', '114311', '411113', // 80-89
'411311', '113141', '114131', '311141', '411131', '232131', '233131', '132131', '113131', '311131', // 90-99
'311311', '331131', '313111', '211412', '211214', '211232', '2331112' // 100-106
'314111', '221411', '431111', '111224', '111413', '121124', '121421', '141122', '141221', '112214', // 60-69
'112412', '122114', '122411', '142112', '142211', '241211', '221114', '413111', '241112', '134111', // 70-79
'111242', '121142', '121241', '114212', '124112', '124211', '411212', '421112', '421211', '212141', // 80-89
'214121', '412121', '111143', '111341', '131141', '114113', '114311', '411113', '411311', '113141', // 90-99
'114131', '311141', '411131', '211412', '211214', '211232', '2331112' // 100-106
]
];
}
}
}

View File

@ -1,16 +1,20 @@
<?php
// test_etiquetas.php - Prueba de etiquetas con Opción 3 (Finas)
require_once 'includes/barcode_generator.php';
$generator = new BarcodeGenerator();
// Simulación de datos para prueba
$codes = ['AFS123456', 'PROD789012', 'TEST345678', 'ITEM901234', 'SKU567890', 'CODE112233', 'BAR445566', 'LBL778899', 'FIN001122'];
$product_names = array_fill(0, 9, 'Producto de Prueba');
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Prueba Etiquetas - Opción 3 (Finas)</title>
<title>Prueba de Etiquetas - REDPOS 4B-2054K</title>
<style>
body {
font-family: Verdana, sans-serif;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
@ -31,66 +35,80 @@ $generator = new BarcodeGenerator();
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.no-print:hover {
background: #218838;
.info-box {
background: white;
padding: 15px;
margin: 10px;
border-radius: 8px;
border-left: 5px solid #28a745;
max-width: 600px;
font-size: 14px;
}
/* Hoja: 96mm x 75mm (Horizontal) */
/* Hoja: 96mm x 75mm */
.etiquetas-container {
width: 96mm;
height: 75mm;
display: grid;
grid-template-columns: repeat(3, 28mm);
grid-template-rows: repeat(3, 21mm);
gap: 2mm;
justify-content: center;
align-content: center;
column-gap: 4mm;
row-gap: 3mm;
padding-left: 2.5mm;
padding-top: 6.5mm; /* Aumentado de 5mm a 6.5mm */
background: white;
box-sizing: border-box;
border: 1px dashed #ccc;
page-break-after: always;
overflow: hidden;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.etiqueta {
width: 28mm;
height: 21mm;
border: 0.1mm solid #eee;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: flex-start;
justify-content: center;
align-items: center;
overflow: hidden;
text-align: center;
padding: 6mm 1mm 1mm 1mm; /* Regresado a 6mm para que no se corte el texto AFS y suba la posición */
padding: 0;
border: 0.1mm dashed #ccc; /* Guía visual solo en pantalla */
}
.barcode-container {
height: 11mm;
height: 11.5mm;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 0 1mm;
margin-top: 1.5mm; /* Añadido margen superior para bajarlo un poco */
padding: 0;
box-sizing: border-box;
width: 100%;
}
.barcode-container svg {
height: 11mm;
height: 11.5mm;
width: auto;
display: block;
margin: 0 auto;
shape-rendering: crispEdges;
}
.sku-text {
font-size: 7px;
margin-top: 1mm;
letter-spacing: 0.5px;
font-family: Arial, sans-serif;
font-size: 3.5mm;
font-weight: normal;
margin-top: 0.5mm;
width: 100%;
line-height: 1;
color: black;
}
@media print {
@page {
size: 96mm 75mm landscape;
size: 96mm 75mm;
margin: 0;
}
body {
@ -98,7 +116,7 @@ $generator = new BarcodeGenerator();
margin: 0;
padding: 0;
}
.no-print {
.no-print, .info-box {
display: none;
}
.etiquetas-container {
@ -114,30 +132,27 @@ $generator = new BarcodeGenerator();
</head>
<body>
<button class="no-print" onclick="window.print()">IMPRIMIR PRUEBA (Opción 3)</button>
<div class="etiquetas-container">
<?php
$skus = ['AFS-0317', 'AFS-0318', 'AFS-0319', 'AFS-0320', 'AFS-0321', 'AFS-0322', 'AFS-0323', 'AFS-0324', 'AFS-0325'];
foreach ($skus as $sku) {
echo '<div class="etiqueta">
<div class="barcode-container">' . $generator->getBarcode($sku, 1.0, 100, 'black', 0) . '</div>
<div class="sku-text">' . $sku . '</div>
</div>';
}
?>
<div class="info-box">
<strong>Configuración Aplicada:</strong><br>
- Hoja: 96x75mm | Margen: L:2.5mm, T:6.5mm | Gaps: C:4mm, R:3mm<br>
- Etiqueta: 28x21mm | Texto: Arial 3.5mm<br>
- Barcode: CODE128, Altura 11.5mm, Narrow Bar 0.25mm (2 dots), Quiet Zone 4mm<br>
- Ajuste: Margen superior de 1.5mm en barcode para centrado visual<br>
- Render: SVG crispEdges (Sin anti-alias)
</div>
<div class="no-print" style="max-width: 600px; background: white; padding: 15px; border-radius: 8px; margin-top: 20px; font-size: 13px; line-height: 1.4; border: 1px solid #ddd;">
<p style="margin-top: 0;"><strong> Formato Estándar Universal:</strong></p>
<ul style="text-align: left; padding-left: 20px;">
<li><b>Formato:</b> Code 128 (Estándar puro).</li>
<li><b>Grosor:</b> Factor 1.0 (Sin engrosar ni adelgazar).</li>
<li><b>Reducción:</b> 0 (Barras estándar).</li>
</ul>
<p>Este es el formato más universal posible. Por favor, imprime esta prueba y verifica si el escáner REDPOS lo reconoce ahora.</p>
<button class="no-print" onclick="window.print()">IMPRIMIR PRUEBA</button>
<div class="etiquetas-container">
<?php foreach ($codes as $code): ?>
<div class="etiqueta">
<div class="barcode-container">
<?php echo $generator->getBarcode($code, 0.25, 11.5, 'black', 4); ?>
</div>
<div class="sku-text"><?php echo htmlspecialchars($code); ?></div>
</div>
<?php endforeach; ?>
</div>
</body>
</html>
</html>