Autosave: 20260217-024246
This commit is contained in:
parent
05af420873
commit
520d1acb1b
@ -1,40 +1,33 @@
|
|||||||
<?php
|
<?php
|
||||||
// get_barcodes_by_product_and_sede.php
|
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
|
|
||||||
$response = ['success' => false, 'barcodes' => []];
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
if (isset($_GET['product_id']) && isset($_GET['sede_id'])) {
|
$productId = isset($_GET['product_id']) ? (int)$_GET['product_id'] : 0;
|
||||||
$productId = (int)$_GET['product_id'];
|
$sedeId = isset($_GET['sede_id']) ? (int)$_GET['sede_id'] : 0;
|
||||||
$sedeId = (int)$_GET['sede_id'];
|
|
||||||
|
|
||||||
try {
|
if ($productId <= 0 || $sedeId <= 0) {
|
||||||
$db = db();
|
echo json_encode([]);
|
||||||
$stmt = $db->prepare("
|
exit;
|
||||||
SELECT codigo_unico, estado
|
|
||||||
FROM unidades_inventario
|
|
||||||
WHERE producto_id = :product_id AND sede_id = :sede_id AND estado != 'Vendido'
|
|
||||||
ORDER BY id DESC
|
|
||||||
");
|
|
||||||
$stmt->bindParam(':product_id', $productId, PDO::PARAM_INT);
|
|
||||||
$stmt->bindParam(':sede_id', $sedeId, PDO::PARAM_INT);
|
|
||||||
$stmt->execute();
|
|
||||||
|
|
||||||
// Usamos FETCH_ASSOC para obtener un array asociativo por cada fila
|
|
||||||
$barcodes = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
$response['success'] = true;
|
|
||||||
$response['barcodes'] = $barcodes;
|
|
||||||
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
// En un entorno de producción, registrarías este error en lugar de mostrarlo
|
|
||||||
$response['message'] = 'Error de base de datos: ' . $e->getMessage();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$response['message'] = 'ID de producto o sede no proporcionado.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo json_encode($response);
|
try {
|
||||||
?>
|
$db = db();
|
||||||
|
$stmt = $db->prepare(
|
||||||
|
"SELECT codigo_unico, estado
|
||||||
|
FROM unidades_inventario
|
||||||
|
WHERE producto_id = :product_id AND sede_id = :sede_id"
|
||||||
|
);
|
||||||
|
$stmt->bindParam(':product_id', $productId, PDO::PARAM_INT);
|
||||||
|
$stmt->bindParam(':sede_id', $sedeId, PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
echo json_encode($results);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(['error' => 'Database error: ' . $e->getMessage()]);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|||||||
@ -16,10 +16,12 @@ if ($selected_sede_id) {
|
|||||||
|
|
||||||
// Se añade p.id para poder usarlo en el botón
|
// Se añade p.id para poder usarlo en el botón
|
||||||
$stmt = $db->prepare("
|
$stmt = $db->prepare("
|
||||||
SELECT p.id, p.nombre, p.sku, ss.quantity
|
SELECT p.id, p.nombre, p.sku, COUNT(ui.id) as quantity
|
||||||
FROM products p
|
FROM products p
|
||||||
JOIN stock_sedes ss ON p.id = ss.product_id
|
JOIN unidades_inventario ui ON p.id = ui.producto_id
|
||||||
WHERE ss.sede_id = ? AND ss.quantity > 0
|
WHERE ui.sede_id = ? AND ui.estado = 'En Almacén'
|
||||||
|
GROUP BY p.id, p.nombre, p.sku
|
||||||
|
HAVING quantity > 0
|
||||||
ORDER BY p.nombre ASC
|
ORDER BY p.nombre ASC
|
||||||
");
|
");
|
||||||
$stmt->execute([$selected_sede_id]);
|
$stmt->execute([$selected_sede_id]);
|
||||||
@ -64,8 +66,7 @@ if ($selected_sede_id) {
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Producto</th>
|
<th>Producto</th>
|
||||||
<th>SKU</th>
|
<th>SKU</th>
|
||||||
<th class="text-end">Cantidad en Stock</th>
|
<th class="text-center">Cantidad en Stock</th>
|
||||||
<th class="text-center">Acciones</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -73,14 +74,14 @@ if ($selected_sede_id) {
|
|||||||
<tr>
|
<tr>
|
||||||
<td><?php echo htmlspecialchars($item['nombre']); ?></td>
|
<td><?php echo htmlspecialchars($item['nombre']); ?></td>
|
||||||
<td><?php echo htmlspecialchars($item['sku']); ?></td>
|
<td><?php echo htmlspecialchars($item['sku']); ?></td>
|
||||||
<td class="text-end"><?php echo htmlspecialchars($item['quantity']); ?></td>
|
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<button class="btn btn-info btn-sm view-codes-btn"
|
<?php if ($item['quantity'] > 0): ?>
|
||||||
data-product-id="<?php echo $item['id']; ?>"
|
<a href="#" class="ver-codigos" data-product-id="<?php echo $item['id']; ?>" data-sede-id="<?php echo $selected_sede_id; ?>">
|
||||||
data-sede-id="<?php echo $selected_sede_id; ?>"
|
<?php echo $item['quantity']; ?>
|
||||||
data-product-name="<?php echo htmlspecialchars($item['nombre']); ?>">
|
</a>
|
||||||
Ver Códigos
|
<?php else: ?>
|
||||||
</button>
|
0
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@ -112,9 +113,7 @@ if ($selected_sede_id) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p><strong>Producto:</strong> <span id="modalProductName"></span></p>
|
<p><strong>Producto:</strong> <span id="modalProductName"></span></p>
|
||||||
<ul id="codesList" class="list-group">
|
<div id="codesTableContainer"></div>
|
||||||
<!-- Los códigos se cargarán aquí dinámicamente -->
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
|
||||||
@ -123,28 +122,21 @@ if ($selected_sede_id) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
console.log("El documento está listo y jQuery está funcionando.");
|
$(".table").on('click', '.ver-codigos', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
$('.view-codes-btn').on('click', function() {
|
|
||||||
console.log("Botón 'Ver Códigos' presionado.");
|
|
||||||
|
|
||||||
var productId = $(this).data('product-id');
|
var productId = $(this).data('product-id');
|
||||||
var sedeId = $(this).data('sede-id');
|
var sedeId = $(this).data('sede-id');
|
||||||
var productName = $(this).data('product-name');
|
var productName = $(this).closest('tr').find('td:first').text();
|
||||||
|
|
||||||
console.log("ID de Producto:", productId, "ID de Sede:", sedeId);
|
|
||||||
|
|
||||||
$('#modalProductName').text(productName);
|
$('#modalProductName').text(productName);
|
||||||
$('#codesList').html('<li class="list-group-item">Cargando...</li>');
|
$('#codesTableContainer').html('<p>Cargando...</p>');
|
||||||
|
|
||||||
var myModal = new bootstrap.Modal(document.getElementById('codesModal'));
|
var myModal = new bootstrap.Modal(document.getElementById('codesModal'));
|
||||||
myModal.show();
|
myModal.show();
|
||||||
|
|
||||||
console.log("Iniciando llamada AJAX a get_barcodes_by_product_and_sede.php");
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'get_barcodes_by_product_and_sede.php',
|
url: 'get_barcodes_by_product_and_sede.php',
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
@ -153,24 +145,29 @@ $(document).ready(function() {
|
|||||||
product_id: productId,
|
product_id: productId,
|
||||||
sede_id: sedeId
|
sede_id: sedeId
|
||||||
},
|
},
|
||||||
success: function(response) {
|
success: function(data) {
|
||||||
console.log("Respuesta AJAX exitosa:", response);
|
|
||||||
var codesListHtml = '';
|
function getBadgeClass(estado) {
|
||||||
if (response && response.success && response.barcodes && response.barcodes.length > 0) {
|
if (estado === 'En Almacén') return 'bg-success';
|
||||||
response.barcodes.forEach(function(barcode) {
|
if (estado === 'Vendido') return 'bg-danger';
|
||||||
codesListHtml += '<li class="list-group-item">' + barcode + '</li>';
|
if (estado === 'Generado') return 'bg-info';
|
||||||
|
return 'bg-secondary';
|
||||||
|
}
|
||||||
|
|
||||||
|
let tableHtml = '<table class="table table-bordered table-striped"><thead><tr><th>Código</th><th>Estado</th></tr></thead><tbody>';
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(item => {
|
||||||
|
const badgeClass = getBadgeClass(item.estado);
|
||||||
|
tableHtml += '<tr><td>' + item.codigo_unico + '</td><td><span class="badge ' + badgeClass + '">' + item.estado + '</span></td></tr>';
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
codesListHtml = '<li class="list-group-item">' + (response.message || 'No se encontraron códigos para este producto en esta sede.') + '</li>';
|
tableHtml += '<tr><td colspan="2" class="text-center">No se encontraron unidades.</td></tr>';
|
||||||
}
|
}
|
||||||
$('#codesList').html(codesListHtml);
|
tableHtml += '</tbody></table>';
|
||||||
|
$('#codesTableContainer').html(tableHtml);
|
||||||
},
|
},
|
||||||
error: function(jqXHR, textStatus, errorThrown) {
|
error: function() {
|
||||||
console.error("Error en la llamada AJAX:");
|
$('#codesTableContainer').html('<p class="text-danger">Error al cargar los códigos.</p>');
|
||||||
console.error("Estado:", textStatus);
|
|
||||||
console.error("Error:", errorThrown);
|
|
||||||
console.error("Respuesta del servidor:", jqXHR.responseText);
|
|
||||||
$('#codesList').html('<li class="list-group-item text-danger">Error al cargar los códigos. Revise la consola para más detalles.</li>');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -21,7 +21,7 @@ try {
|
|||||||
// 1. Datos para las tarjetas de resumen
|
// 1. Datos para las tarjetas de resumen
|
||||||
$total_productos = $pdo->query("SELECT COUNT(*) FROM products")->fetchColumn();
|
$total_productos = $pdo->query("SELECT COUNT(*) FROM products")->fetchColumn();
|
||||||
$total_sedes = $pdo->query("SELECT COUNT(*) FROM sedes")->fetchColumn();
|
$total_sedes = $pdo->query("SELECT COUNT(*) FROM sedes")->fetchColumn();
|
||||||
$total_stock = $pdo->query("SELECT SUM(quantity) FROM stock_sedes")->fetchColumn();
|
$total_stock = $pdo->query("SELECT COUNT(*) FROM unidades_inventario WHERE estado = 'En Almacén'")->fetchColumn();
|
||||||
|
|
||||||
// 2. Datos para la tabla de inventario
|
// 2. Datos para la tabla de inventario
|
||||||
$sedes_stmt = $pdo->query("SELECT id, nombre FROM sedes ORDER BY nombre");
|
$sedes_stmt = $pdo->query("SELECT id, nombre FROM sedes ORDER BY nombre");
|
||||||
@ -30,7 +30,7 @@ try {
|
|||||||
$products_stmt = $pdo->query("SELECT id, nombre, sku 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 producto_id, sede_id, COUNT(*) as quantity FROM unidades_inventario WHERE estado = 'En Almacén' GROUP BY producto_id, sede_id");
|
||||||
$stock_data = $stock_stmt->fetchAll(PDO::FETCH_ASSOC);
|
$stock_data = $stock_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$inventario = [];
|
$inventario = [];
|
||||||
@ -44,9 +44,9 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($stock_data as $stock_item) {
|
foreach ($stock_data as $stock_item) {
|
||||||
if (isset($inventario[$stock_item['product_id']])) {
|
if (isset($inventario[$stock_item['producto_id']])) {
|
||||||
$inventario[$stock_item['product_id']]['sedes'][$stock_item['sede_id']] = $stock_item['quantity'];
|
$inventario[$stock_item['producto_id']]['sedes'][$stock_item['sede_id']] = $stock_item['quantity'];
|
||||||
$inventario[$stock_item['product_id']]['total'] += $stock_item['quantity'];
|
$inventario[$stock_item['producto_id']]['total'] += $stock_item['quantity'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,13 +192,21 @@ try {
|
|||||||
<?php if (empty($inventario)): ?>
|
<?php if (empty($inventario)): ?>
|
||||||
<tr><td colspan="<?php echo count($sedes) + 3; ?>" 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 $product_id => $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><?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 $sede_id => $cantidad): ?>
|
||||||
<td class="text-center"><?php echo $cantidad; ?></td>
|
<td class="text-center">
|
||||||
|
<?php if ($cantidad > 0): ?>
|
||||||
|
<a href="#" class="ver-codigos" data-product-id="<?php echo $product_id; ?>" data-sede-id="<?php echo $sede_id; ?>">
|
||||||
|
<?php echo $cantidad; ?>
|
||||||
|
</a>
|
||||||
|
<?php else: ?>
|
||||||
|
0
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@ -326,14 +334,23 @@ $(document).ready(function() {
|
|||||||
product_id: productId,
|
product_id: productId,
|
||||||
sede_id: sedeId
|
sede_id: sedeId
|
||||||
},
|
},
|
||||||
success: function(response) {
|
success: function(data) {
|
||||||
var tableHtml = '<table class="table table-bordered"><thead><tr><th>Código</th><th>Estado</th></tr></thead><tbody>';
|
|
||||||
if (response && response.success && response.barcodes && response.barcodes.length > 0) {
|
function getBadgeClass(estado) {
|
||||||
response.barcodes.forEach(function(item) {
|
if (estado === 'En Almacén') return 'bg-success';
|
||||||
tableHtml += '<tr><td>' + item.codigo_unico + '</td><td>' + item.estado + '</td></tr>';
|
if (estado === 'Vendido') return 'bg-danger';
|
||||||
|
if (estado === 'Generado') return 'bg-info';
|
||||||
|
return 'bg-secondary';
|
||||||
|
}
|
||||||
|
|
||||||
|
let tableHtml = '<table class="table table-bordered table-striped"><thead><tr><th>Código</th><th>Estado</th></tr></thead><tbody>';
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(item => {
|
||||||
|
const badgeClass = getBadgeClass(item.estado);
|
||||||
|
tableHtml += '<tr><td>' + item.codigo_unico + '</td><td><span class="badge ' + badgeClass + '">' + item.estado + '</span></td></tr>';
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
tableHtml += '<tr><td colspan="2">' + (response.message || 'No se encontraron códigos.') + '</td></tr>';
|
tableHtml += '<tr><td colspan="2" class="text-center">No se encontraron unidades.</td></tr>';
|
||||||
}
|
}
|
||||||
tableHtml += '</tbody></table>';
|
tableHtml += '</tbody></table>';
|
||||||
$('#codesTableContainer').html(tableHtml);
|
$('#codesTableContainer').html(tableHtml);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user