Files
pos_heidiver/app/Services/EAN13Service.php
T
2026-01-06 15:35:59 -05:00

86 lines
3.3 KiB
PHP

<?php
namespace App\Services;
use App\Models\Producto;
use App\Models\ProductVariant;
class EAN13Service
{
/**
* Genera un código de barras EAN-13 único.
*
* @param string $countryCode Código de país (2 dígitos)
* @param int $categoryId ID de la categoría (2 dígitos)
* @param int $productId ID del producto (5 dígitos)
* @param int|null $variantId ID de la variante (2 dígitos, opcional)
* @return string Código de barras EAN-13
* @throws \Exception Si hay un error en la generación del código
*/
public function generateUniqueBarcode($countryCode, $categoryId, $productId, $variantId = null)
{
// Formatear los valores con ceros a la izquierda
$categoryCode = str_pad($categoryId, 2, '0', STR_PAD_LEFT);
$productCode = str_pad($productId, 5, '0', STR_PAD_LEFT);
$variantCode = str_pad($variantId ?? 0, 3, '0', STR_PAD_LEFT);
// Generar los primeros 12 dígitos del código EAN-13
$barcodeBase = $countryCode . $categoryCode . $productCode . $variantCode;
// Validar que la longitud sea exactamente 12 caracteres
if (strlen($barcodeBase) !== 12) {
throw new \Exception("Error: El código base del EAN-13 no tiene 12 caracteres: $barcodeBase");
}
// Intentar generar un código único hasta 5 veces
$maxAttempts = 5;
$uniqueBarcode = null;
foreach (range(1, $maxAttempts) as $attempt) {
// Calcular el dígito de control
$checkDigit = $this->calculateCheckDigit($barcodeBase);
$barcode = $barcodeBase . $checkDigit;
// Verificar si el código de barras ya existe en la base de datos
$existsInProductVariant = ProductVariant::where('barcode', $barcode)->exists();
$existsInProducto = Producto::where('codigo_barras', $barcode)->exists();
if (!$existsInProductVariant && !$existsInProducto) {
// Si no existe, asignar el código único y salir del ciclo
$uniqueBarcode = $barcode;
break;
}
// Si existe, modificar el código base agregando un sufijo incremental
$suffix = str_pad($attempt, 3, '0', STR_PAD_LEFT); // Agregar un sufijo de 3 dígitos
$barcodeBase = substr($barcodeBase, 0, -3) . $suffix; // Reemplazar los últimos 3 dígitos con el sufijo
}
// Retornar el código único si se encontró, o null si no se pudo generar
return $uniqueBarcode;
}
/**
* Calcula el dígito de control de un código EAN-13.
*
* @param string $barcodeBase Los primeros 12 dígitos del código EAN-13
* @return int Dígito de control calculado
* @throws \Exception Si el código base no tiene 12 caracteres
*/
private function calculateCheckDigit($barcodeBase)
{
if (strlen($barcodeBase) !== 12) {
throw new \Exception("Error: El código base para el dígito de control no tiene 12 caracteres: $barcodeBase");
}
$sum = 0;
for ($i = 0; $i < 12; $i++) {
$digit = (int) $barcodeBase[$i];
$sum += ($i % 2 === 0) ? $digit : $digit * 3;
}
$remainder = $sum % 10;
return ($remainder === 0) ? 0 : 10 - $remainder;
}
}