diff --git a/assets/uploads/vouchers/6a0f569864c5a-Screenshot_356.png b/assets/uploads/vouchers/6a0f569864c5a-Screenshot_356.png new file mode 100644 index 00000000..9bf0941d Binary files /dev/null and b/assets/uploads/vouchers/6a0f569864c5a-Screenshot_356.png differ diff --git a/imprimir_etiquetas_termica.php b/imprimir_etiquetas_termica.php index 47611fd0..6d6a497e 100644 --- a/imprimir_etiquetas_termica.php +++ b/imprimir_etiquetas_termica.php @@ -66,7 +66,7 @@ if (empty($codes)) { align-items: center; overflow: hidden; text-align: center; - padding: 1mm; + padding: 3mm 1mm 1mm 1mm; /* Aumentado padding superior de 1mm a 3mm para bajar el contenido */ border: 0.1mm solid #eee; /* Guía visual en pantalla */ } @@ -83,20 +83,22 @@ if (empty($codes)) { } .barcode-container { - height: 9.12mm; /* Altura exacta solicitada */ + height: 9mm; /* Reducido de 11mm a 9mm */ display: flex; justify-content: center; align-items: center; margin: 1mm 0; /* Margen vertical */ - padding: 0 2mm; /* Margen lateral de 2mm solicitado */ + padding: 0 1mm; /* Reducido de 2mm a 1mm para maximizar grosor de barras */ box-sizing: border-box; width: 100%; /* Ocupa el ancho de la etiqueta para centrar */ } .barcode-container svg { - height: 9.12mm; - width: auto; /* Que el ancho sea proporcional a la cantidad de caracteres */ + height: 9mm; + width: auto; shape-rendering: crispEdges; + display: block; + margin: 0 auto; } .sku-text { @@ -150,9 +152,10 @@ if (empty($codes)) {
getBarcode($code, 1, 70); + // widthFactor 1.2 + altura 72 en el SVG, escalado a 9mm en CSS + // resulta en una barra mínima de ~0.15mm (9 / 72 * 1.2) + // Esto reduce la densidad y mejora la lectura sin ser demasiado grueso. + echo $generator->getBarcode($code, 1.2, 72); ?>
diff --git a/includes/barcode_generator.php b/includes/barcode_generator.php index 156c486c..cee34e57 100644 --- a/includes/barcode_generator.php +++ b/includes/barcode_generator.php @@ -11,23 +11,27 @@ class BarcodeGenerator $this->barcode_codes = $this->getCode128Map(); } - public function getBarcode($code, $widthFactor = 2, $height = 50, $foregroundColor = 'black') + public function getBarcode($code, $widthFactor = 1, $height = 50, $foregroundColor = 'black') { $barcodeData = $this->getBarcodeData($code); + if (!$barcodeData) return ''; $bars = ''; - $x = 0; + $quietZone = 10; // 10 modules of quiet zone + $x = $quietZone; - // Generate SVG bars - foreach (str_split($barcodeData['bars']) as $bar) { - $width = $widthFactor * (int)$bar; - if ($x % 2 == 0) { // 0, 2, 4... are black bars + $barArray = str_split($barcodeData['bars']); + for ($i = 0; $i < count($barArray); $i++) { + $width = $widthFactor * (int)$barArray[$i]; + if ($i % 2 == 0) { // Even indices are bars, odd are spaces $bars .= ''; } $x += $width; } - $svg = ''; + $totalWidth = $x + $quietZone; + $svg = ''; + $svg .= ''; $svg .= $bars; $svg .= ''; @@ -36,36 +40,61 @@ class BarcodeGenerator private function getBarcodeData($code) { - // For simplicity, we'll stick to Code Set B - $codeSet = 'B'; - $data = ''; - $sum = 104; // Start code B - $mult = 1; - - foreach (str_split($code) as $char) { - $value = $this->getCharValue($codeSet, $char); - if ($value === null) { - // Fallback for unsupported characters, or switch sets (more complex) - // For now, we'll just skip them to avoid errors - continue; + $i = 0; + $len = strlen($code); + $indices = []; + $currentMode = 'B'; + + $indices[] = 104; // Start B + + while ($i < $len) { + // Check for 4 or more digits to switch to Mode C + $digitCount = 0; + while ($i + $digitCount < $len && is_numeric($code[$i + $digitCount])) { + $digitCount++; + } + + if ($digitCount >= 4) { + if ($currentMode !== 'C') { + $indices[] = 99; // Switch to C + $currentMode = 'C'; + } + + while ($digitCount >= 2) { + $indices[] = (int)substr($code, $i, 2); + $i += 2; + $digitCount -= 2; + } + } + + if ($i < $len) { + if ($currentMode === 'C') { + $indices[] = 100; // Switch to B + $currentMode = 'B'; + } + $val = $this->getCharValue('B', $code[$i]); + if ($val !== null) $indices[] = $val; + $i++; } - $data .= str_pad($value, 2, '0', STR_PAD_LEFT); - $sum += ($value * $mult); - $mult++; } + // Checksum calculation + $sum = $indices[0]; + for ($k = 1; $k < count($indices); $k++) { + $sum += ($indices[$k] * $k); + } $checksum = $sum % 103; - $data .= str_pad($checksum, 2, '0', STR_PAD_LEFT); + $indices[] = $checksum; + $indices[] = 106; // Stop - // Start, data, checksum, stop - $full_code = '104' . $data . '106'; $bars = ''; - for ($i = 0; $i < strlen($full_code); $i += 2) { - $index = (int)substr($full_code, $i, 2); - $bars .= $this->barcode_codes['bars'][$index]; + foreach ($indices as $index) { + if (isset($this->barcode_codes['bars'][$index])) { + $bars .= $this->barcode_codes['bars'][$index]; + } } - return ['bars' => $bars, 'code' => $full_code]; + return ['bars' => $bars]; } private function getCharValue($set, $char) @@ -73,7 +102,7 @@ class BarcodeGenerator if (isset($this->barcode_codes[$set][$char])) { return $this->barcode_codes[$set][$char]; } - return null; // Character not in set + return null; } private function getCode128Map() @@ -87,12 +116,25 @@ class BarcodeGenerator '@' => 32, 'A' => 33, 'B' => 34, 'C' => 35, 'D' => 36, 'E' => 37, 'F' => 38, 'G' => 39, 'H' => 40, 'I' => 41, 'J' => 42, 'K' => 43, 'L' => 44, 'M' => 45, 'N' => 46, 'O' => 47, 'P' => 48, 'Q' => 49, 'R' => 50, 'S' => 51, 'T' => 52, 'U' => 53, 'V' => 54, 'W' => 55, - 'X' => 56, 'Y' => 57, 'Z' => 58, '[' => 59, '\\' => 60, ']' => 61, '^' => 62, '_' => 63 + 'X' => 56, 'Y' => 57, 'Z' => 58, '[' => 59, '\\' => 60, ']' => 61, '^' => 62, '_' => 63, + '`' => 64, 'a' => 65, 'b' => 66, 'c' => 67, 'd' => 68, 'e' => 69, 'f' => 70, 'g' => 71, + 'h' => 72, 'i' => 73, 'j' => 74, 'k' => 75, 'l' => 76, 'm' => 77, 'n' => 78, 'o' => 79, + 'p' => 80, 'q' => 81, 'r' => 82, 's' => 83, 't' => 84, 'u' => 85, 'v' => 86, 'w' => 87, + 'x' => 88, 'y' => 89, 'z' => 90, '{' => 91, '|' => 92, '}' => 93, '~' => 94 ], 'bars' => [ - '212222', '222122', '222221', '121223', '121322', '131222', '122213', '122312', '132212', '221213', '221312', '231212', '112232', '122132', '122231', '113222', '123122', '123221', '223211', '221132', '221231', '213212', '223112', '312131', '311222', '321122', '321221', '312212', '322112', '322211', '212123', '212321', '232121', '111323', '131123', '131321', '112313', '132113', '132311', '211313', '231113', '231311', '112133', '112331', '132131', '113123', '113321', '133121', '313121', '211331', '231131', '213113', '213311', '213131', '311123', '311321', '331121', '312113', '312311', '332111', '314111', '221411', '413111', '111224', '111421', '121124', '121421', '141122', '141221', '112214', '112412', '122114', '122411', '142112', '142211', '241211', '221114', '411122', '411221', '421121', '421211', '212141', '214121', '412121', '111143', '111341', '131141', '114113', '114311', '411113', '411311', '113141', '114131', '311141', '411131', '211412', '211214', '211232', '2331112' + '212222', '222122', '222221', '121223', '121322', '131222', '122213', '122312', '132212', '221213', // 0-9 + '221312', '231212', '112232', '122132', '122231', '113222', '123122', '123221', '223211', '221132', // 10-19 + '221231', '213212', '223112', '312131', '311222', '321122', '321221', '312212', '322112', '322211', // 20-29 + '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 ] ]; } } -?> \ No newline at end of file diff --git a/test_etiquetas.php b/test_etiquetas.php index 6baed7fc..a833bac4 100644 --- a/test_etiquetas.php +++ b/test_etiquetas.php @@ -61,7 +61,7 @@ $generator = new BarcodeGenerator(); align-items: center; overflow: hidden; text-align: center; - padding: 1mm; + padding: 3mm 1mm 1mm 1mm; /* Aumentado padding superior de 1mm a 3mm para bajar el contenido */ } .producto-nombre { @@ -77,20 +77,22 @@ $generator = new BarcodeGenerator(); } .barcode-container { - height: 9.12mm; /* Altura solicitada: 9.12mm */ + height: 9mm; /* Reducido de 11mm a 9mm */ display: flex; justify-content: center; align-items: center; margin: 1mm 0; - padding: 0 2mm; /* Margen de 2mm solicitado */ + padding: 0 1mm; /* Reducido de 2mm a 1mm para maximizar grosor de barras */ box-sizing: border-box; width: 100%; } .barcode-container svg { - height: 9.12mm; + height: 9mm; width: auto; shape-rendering: crispEdges; + display: block; + margin: 0 auto; } .sku-text { @@ -126,7 +128,7 @@ $generator = new BarcodeGenerator(); - +
PRODUCTO
getBarcode($sku, 1, 70); + // widthFactor 1.2 + altura 72 en el SVG, escalado a 9mm en CSS + // resulta en una barra mínima de ~0.15mm (9 / 72 * 1.2) + // Esto reduce la densidad y mejora la lectura sin ser demasiado grueso. + echo $generator->getBarcode($sku, 1.2, 72); ?>
@@ -151,11 +154,12 @@ $generator = new BarcodeGenerator();

✅ Especificaciones Aplicadas: