Autosave: 20260212-165014

This commit is contained in:
Flatlogic Bot 2026-02-12 16:50:14 +00:00
parent d37c7e72bd
commit f59550e0b4
16 changed files with 70 additions and 55 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

View File

@ -0,0 +1,3 @@
ALTER TABLE `products`
ADD COLUMN `codigo_base` VARCHAR(20) DEFAULT NULL,
ADD COLUMN `contador_etiquetas` INT DEFAULT 0;

View File

@ -71,6 +71,12 @@ include 'layout_header.php';
<input type="text" class="form-control" id="nombre" name="nombre" value="<?php echo htmlspecialchars($product['nombre']); ?>" required> <input type="text" class="form-control" id="nombre" name="nombre" value="<?php echo htmlspecialchars($product['nombre']); ?>" required>
</div> </div>
<div class="form-group">
<label for="codigo_base">Prefijo para Etiquetas (Opcional)</label>
<input type="text" class="form-control" id="codigo_base" name="codigo_base" value="<?php echo htmlspecialchars($product['codigo_base'] ?? ''); ?>">
<small class="form-text text-muted">Ej: "AFS" para Anillo Feng Shui. Si lo dejas vacío, se usarán las iniciales del nombre.</small>
</div>
<div class="form-group"> <div class="form-group">
<label for="provincia_id">Provincia (Opcional)</label> <label for="provincia_id">Provincia (Opcional)</label>
<select class="form-control" id="provincia_id" name="provincia_id"> <select class="form-control" id="provincia_id" name="provincia_id">

View File

@ -2,7 +2,7 @@
$pageTitle = "Generador de Etiquetas"; $pageTitle = "Generador de Etiquetas";
include 'layout_header.php'; include 'layout_header.php';
include 'db/config.php'; include 'db/config.php';
require_once 'includes/barcode_generator.php'; // Added this line
// Fetch products for the dropdown // Fetch products for the dropdown
$products = []; $products = [];
@ -15,51 +15,50 @@ try {
} }
// Handle form submission // Handle form submission
$generated_codes = []; // Initialize array to hold codes for display $generated_codes = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$producto_id = $_POST['producto_id'] ?? null; $producto_id = $_POST['producto_id'] ?? null;
$cantidad = isset($_POST['cantidad']) ? (int)$_POST['cantidad'] : 0; $cantidad = isset($_POST['cantidad']) ? (int)$_POST['cantidad'] : 0;
if ($producto_id && $cantidad > 0 && $cantidad <= 1000) { if ($producto_id && $cantidad > 0 && $cantidad <= 1000) {
// Find product name to generate initials
$product_name = '';
foreach ($products as $p) {
if ($p['id'] == $producto_id) {
$product_name = $p['nombre'];
break;
}
}
$initials = '';
if (!empty($product_name)) {
$words = preg_split('/\s+/', trim($product_name));
foreach ($words as $w) {
if (isset($w[0])) {
$initials .= strtoupper($w[0]);
}
}
}
$db = db(); $db = db();
try { try {
$db->beginTransaction(); $db->beginTransaction();
// Prepare statement for insertion
$stmt = $db->prepare("INSERT INTO unidades_inventario (codigo_unico, producto_id) VALUES (?, ?)");
for ($i = 0; $i < $cantidad; $i++) { // 1. Lock the product row and get current counter and code base
// Generate a unique code with product initials $stmt = $db->prepare("SELECT codigo_base, contador_etiquetas FROM products WHERE id = ? FOR UPDATE");
$unique_part = strtoupper(uniqid()); $stmt->execute([$producto_id]);
$unique_code = ($initials ? $initials . '-' : '') . $producto_id . '-' . $unique_part; $product_data = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product_data) {
throw new Exception("Producto no encontrado.");
}
$codigo_base = $product_data['codigo_base'];
$contador_actual = (int)$product_data['contador_etiquetas'];
// Prepare statement for insertion into unidades_inventario
$insert_stmt = $db->prepare("INSERT INTO unidades_inventario (codigo_unico, producto_id) VALUES (?, ?)");
// 2. Generate new codes
for ($i = 1; $i <= $cantidad; $i++) {
$nuevo_contador = $contador_actual + $i;
$numero_formateado = str_pad($nuevo_contador, 4, '0', STR_PAD_LEFT);
$unique_code = $codigo_base . '-' . $numero_formateado;
$stmt->execute([$unique_code, $producto_id]); $insert_stmt->execute([$unique_code, $producto_id]);
$generated_codes[] = $unique_code; $generated_codes[] = $unique_code;
} }
// 3. Update the counter in the products table
$nuevo_total_contador = $contador_actual + $cantidad;
$update_stmt = $db->prepare("UPDATE products SET contador_etiquetas = ? WHERE id = ?");
$update_stmt->execute([$nuevo_total_contador, $producto_id]);
$db->commit(); $db->commit();
$_SESSION['success_message'] = 'Se generaron ' . count($generated_codes) . ' códigos exitosamente.'; $_SESSION['success_message'] = 'Se generaron ' . count($generated_codes) . ' códigos exitosamente.';
} catch (PDOException $e) { } catch (Exception $e) {
$db->rollBack(); $db->rollBack();
$_SESSION['error_message'] = 'Error al generar los códigos: ' . $e->getMessage(); $_SESSION['error_message'] = 'Error al generar los códigos: ' . $e->getMessage();
} }
@ -113,7 +112,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<?php <?php
if (!empty($generated_codes)) { if (!empty($generated_codes)) {
$generator = new BarcodeGenerator();
?> ?>
<div class="card mt-4"> <div class="card mt-4">
<div class="card-header d-flex justify-content-between align-items-center"> <div class="card-header d-flex justify-content-between align-items-center">
@ -133,13 +131,7 @@ if (!empty($generated_codes)) {
<?php foreach ($generated_codes as $code): ?> <?php foreach ($generated_codes as $code): ?>
<div class="col-lg-4 col-md-6 text-center mb-4"> <div class="col-lg-4 col-md-6 text-center mb-4">
<div class="barcode-container" style="min-height: 70px;"> <div class="barcode-container" style="min-height: 70px;">
<?php <img src="https://barcode.tec-it.com/barcode.ashx?data=<?php echo urlencode($code); ?>&code=Code128" alt="Barcode for <?php echo htmlspecialchars($code); ?>" style="max-height: 50px;">
try {
echo $generator->getBarcode($code);
} catch (Exception $e) {
echo '<div class="alert alert-danger">Error al generar código de barras.</div>';
}
?>
</div> </div>
<code><?php echo htmlspecialchars($code); ?></code> <code><?php echo htmlspecialchars($code); ?></code>
</div> </div>
@ -149,4 +141,4 @@ if (!empty($generated_codes)) {
</div> </div>
<?php } ?> <?php } ?>
<?php include 'layout_footer.php'; ?> <?php include 'layout_footer.php'; ?>

View File

@ -1,5 +1,5 @@
<?php <?php
require_once 'includes/barcode_generator.php';
$codes = $_POST['codes'] ?? []; $codes = $_POST['codes'] ?? [];
@ -8,7 +8,7 @@ if (empty($codes)) {
// For now, we'll just show a blank page if no codes are provided. // For now, we'll just show a blank page if no codes are provided.
} }
$generator = new BarcodeGenerator();
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="es"> <html lang="es">
@ -80,13 +80,7 @@ $generator = new BarcodeGenerator();
<?php foreach ($codes as $code): ?> <?php foreach ($codes as $code): ?>
<div class="label"> <div class="label">
<div class="barcode-svg"> <div class="barcode-svg">
<?php <img src="https://barcode.tec-it.com/barcode.ashx?data=<?php echo urlencode($code); ?>&code=Code128" alt="Barcode for <?php echo htmlspecialchars($code); ?>" style="max-height: 50px;">
try {
echo $generator->getBarcode($code, 2, 50);
} catch (Exception $e) {
echo '<div class="alert alert-danger p-1">Error</div>';
}
?>
</div> </div>
<div class="code-text"> <div class="code-text">
<code><?php echo htmlspecialchars($code); ?></code> <code><?php echo htmlspecialchars($code); ?></code>

View File

@ -27,7 +27,7 @@ try {
$sedes_stmt = $pdo->query("SELECT id, nombre FROM sedes ORDER BY nombre"); $sedes_stmt = $pdo->query("SELECT id, nombre FROM sedes ORDER BY nombre");
$sedes = $sedes_stmt->fetchAll(PDO::FETCH_ASSOC); $sedes = $sedes_stmt->fetchAll(PDO::FETCH_ASSOC);
$products_stmt = $pdo->query("SELECT id, nombre FROM products ORDER BY nombre"); $products_stmt = $pdo->query("SELECT id, nombre, sku FROM products ORDER BY nombre");
$products = $products_stmt->fetchAll(PDO::FETCH_ASSOC); $products = $products_stmt->fetchAll(PDO::FETCH_ASSOC);
$stock_stmt = $pdo->query("SELECT product_id, sede_id, quantity FROM stock_sedes"); $stock_stmt = $pdo->query("SELECT product_id, sede_id, quantity FROM stock_sedes");
@ -37,6 +37,7 @@ try {
foreach ($products as $product) { foreach ($products as $product) {
$inventario[$product['id']] = [ $inventario[$product['id']] = [
'nombre' => $product['nombre'], 'nombre' => $product['nombre'],
'sku' => $product['sku'],
'total' => 0, 'total' => 0,
'sedes' => array_fill_keys(array_column($sedes, 'id'), 0) 'sedes' => array_fill_keys(array_column($sedes, 'id'), 0)
]; ];
@ -180,6 +181,7 @@ try {
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
<th>Producto</th> <th>Producto</th>
<th>SKU</th>
<th class="text-center">Stock Total</th> <th class="text-center">Stock Total</th>
<?php foreach ($sedes as $sede): ?> <?php foreach ($sedes as $sede): ?>
<th class="text-center"><?php echo htmlspecialchars($sede['nombre']); ?></th> <th class="text-center"><?php echo htmlspecialchars($sede['nombre']); ?></th>
@ -188,11 +190,12 @@ try {
</thead> </thead>
<tbody> <tbody>
<?php if (empty($inventario)): ?> <?php if (empty($inventario)): ?>
<tr><td colspan="<?php echo count($sedes) + 2; ?>" class="text-center">No hay productos.</td></tr> <tr><td colspan="<?php echo count($sedes) + 3; ?>" class="text-center">No hay productos.</td></tr>
<?php else: ?> <?php else: ?>
<?php foreach ($inventario as $datos_producto): ?> <?php foreach ($inventario as $datos_producto): ?>
<tr> <tr>
<td><?php echo htmlspecialchars($datos_producto['nombre']); ?></td> <td><?php echo htmlspecialchars($datos_producto['nombre']); ?></td>
<td><?php echo htmlspecialchars($datos_producto['sku']); ?></td>
<td class="text-center fw-bold"><?php echo $datos_producto['total']; ?></td> <td class="text-center fw-bold"><?php echo $datos_producto['total']; ?></td>
<?php foreach ($datos_producto['sedes'] as $cantidad): ?> <?php foreach ($datos_producto['sedes'] as $cantidad): ?>
<td class="text-center"><?php echo $cantidad; ?></td> <td class="text-center"><?php echo $cantidad; ?></td>

View File

@ -2,10 +2,23 @@
session_start(); session_start();
require_once 'db/config.php'; require_once 'db/config.php';
// Función para generar el código base a partir de las iniciales
function generar_codigo_base($nombre) {
$palabras = explode(' ', trim($nombre));
$iniciales = '';
foreach ($palabras as $palabra) {
if (!empty($palabra)) {
$iniciales .= strtoupper($palabra[0]);
}
}
return $iniciales;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Recoger todos los datos del formulario // Recoger todos los datos del formulario
$id = $_POST['id'] ?? null; $id = $_POST['id'] ?? null;
$nombre = $_POST['nombre'] ?? ''; $nombre = $_POST['nombre'] ?? '';
$codigo_base = $_POST['codigo_base'] ?? '';
$sku = !empty($_POST['sku']) ? $_POST['sku'] : null; $sku = !empty($_POST['sku']) ? $_POST['sku'] : null;
$costo = !empty($_POST['costo']) ? (float)$_POST['costo'] : 0.00; $costo = !empty($_POST['costo']) ? (float)$_POST['costo'] : 0.00;
$precio_venta = !empty($_POST['precio_venta']) ? (float)$_POST['precio_venta'] : 0.00; $precio_venta = !empty($_POST['precio_venta']) ? (float)$_POST['precio_venta'] : 0.00;
@ -14,20 +27,24 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$show_on_panel = isset($_POST['show_on_panel']) ? 1 : 0; $show_on_panel = isset($_POST['show_on_panel']) ? 1 : 0;
// Generar código base si está vacío
if (empty($codigo_base)) {
$codigo_base = generar_codigo_base($nombre);
}
$db = db(); $db = db();
if (!empty($id)) { if (!empty($id)) {
// Actualizar producto existente // Actualizar producto existente
$sql = "UPDATE products SET nombre = ?, sku = ?, costo = ?, precio_venta = ?, description = ?, provincia_id = ?, show_on_panel = ? WHERE id = ?"; $sql = "UPDATE products SET nombre = ?, sku = ?, costo = ?, precio_venta = ?, description = ?, provincia_id = ?, show_on_panel = ?, codigo_base = ? WHERE id = ?";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->execute([$nombre, $sku, $costo, $precio_venta, $description, $provincia_id, $show_on_panel, $id]); $stmt->execute([$nombre, $sku, $costo, $precio_venta, $description, $provincia_id, $show_on_panel, $codigo_base, $id]);
$_SESSION['success_message'] = "Producto actualizado exitosamente."; $_SESSION['success_message'] = "Producto actualizado exitosamente.";
} else { } else {
// Crear nuevo producto // Crear nuevo producto
// No se insertan columnas generadas como ganancia_unidad, ingreso_total, ganancia_total $sql = "INSERT INTO products (nombre, sku, costo, precio_venta, description, provincia_id, show_on_panel, codigo_base, unidades_vendidas) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)";
$sql = "INSERT INTO products (nombre, sku, costo, precio_venta, description, provincia_id, show_on_panel, unidades_vendidas) VALUES (?, ?, ?, ?, ?, ?, ?, 0)";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->execute([$nombre, $sku, $costo, $precio_venta, $description, $provincia_id, $show_on_panel]); $stmt->execute([$nombre, $sku, $costo, $precio_venta, $description, $provincia_id, $show_on_panel, $codigo_base]);
$_SESSION['success_message'] = "Producto creado exitosamente."; $_SESSION['success_message'] = "Producto creado exitosamente.";
} }