209 lines
5.9 KiB
JavaScript
209 lines
5.9 KiB
JavaScript
const productos = [];
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const btnMas = document.querySelector(".btn-mas");
|
|
const btnRegistrar = document.querySelector("#btn-registrar-venta");
|
|
const codigoInput = document.querySelector(
|
|
'input[placeholder="Código del Producto"]'
|
|
);
|
|
const nombreInput = document.querySelector(
|
|
'input[placeholder="Nombre del Producto"]'
|
|
);
|
|
const cantidadInput = document.querySelector(
|
|
'input[placeholder="Cantidad"]'
|
|
);
|
|
|
|
const buscarProducto = (terminoBusqueda) => {
|
|
return fetch(
|
|
`../php/Buscar_Producto_Ventas.php?codigo=${encodeURIComponent(terminoBusqueda)}`
|
|
).then((response) => response.json());
|
|
};
|
|
|
|
const completarProductoDesdeInputs = (event) => {
|
|
// Identificamos cuál de los dos inputs disparó la acción
|
|
const inputActual = event ? event.target : null;
|
|
|
|
// 1. Si el usuario vació el input en el que está trabajando, limpiamos ambos y salimos
|
|
if (inputActual && inputActual.value.trim() === "") {
|
|
codigoInput.value = "";
|
|
nombreInput.value = "";
|
|
return;
|
|
}
|
|
|
|
const codigo = codigoInput.value.trim();
|
|
const nombre = nombreInput.value.trim();
|
|
|
|
// 2. Buscamos priorizando el input que el usuario acaba de modificar
|
|
let terminoBusqueda = "";
|
|
if (inputActual === codigoInput) {
|
|
terminoBusqueda = codigo;
|
|
} else if (inputActual === nombreInput) {
|
|
terminoBusqueda = nombre;
|
|
} else {
|
|
terminoBusqueda = codigo || nombre;
|
|
}
|
|
|
|
// Si por alguna razón ambos están vacíos, aseguramos la limpieza
|
|
if (!terminoBusqueda) {
|
|
codigoInput.value = "";
|
|
nombreInput.value = "";
|
|
return;
|
|
}
|
|
|
|
buscarProducto(terminoBusqueda)
|
|
.then((data) => {
|
|
if (!data || !data.ID_Producto) {
|
|
return;
|
|
}
|
|
|
|
codigoInput.value = data.ID_Producto;
|
|
nombreInput.value = data.Descripcion;
|
|
})
|
|
.catch((error) => {
|
|
console.error("Error al autocompletar el producto:", error);
|
|
});
|
|
};
|
|
|
|
[codigoInput, nombreInput].forEach((input) => {
|
|
// Cuando sale del campo (hace clic afuera)
|
|
input.addEventListener("blur", completarProductoDesdeInputs);
|
|
|
|
// Cuando presiona Enter
|
|
input.addEventListener("keydown", (event) => {
|
|
if (event.key === "Enter") {
|
|
event.preventDefault();
|
|
completarProductoDesdeInputs(event);
|
|
}
|
|
});
|
|
|
|
// NUEVO: Cuando borra el contenido en tiempo real
|
|
input.addEventListener("input", (event) => {
|
|
if (event.target.value.trim() === "") {
|
|
codigoInput.value = "";
|
|
nombreInput.value = "";
|
|
}
|
|
});
|
|
});
|
|
btnMas.addEventListener("click", () => {
|
|
const codigo = codigoInput.value.trim();
|
|
const nombre = nombreInput.value.trim();
|
|
const cantidad = parseInt(cantidadInput.value);
|
|
|
|
if (!codigo && !nombre) {
|
|
alert("Debe ingresar el Código o el Nombre del producto.");
|
|
return;
|
|
}
|
|
|
|
if (isNaN(cantidad) || cantidad <= 0) {
|
|
alert("Ingrese una cantidad válida mayor a 0.");
|
|
return;
|
|
}
|
|
|
|
const terminoBusqueda = codigo || nombre;
|
|
|
|
buscarProducto(terminoBusqueda)
|
|
.then((data) => {
|
|
console.log("Producto obtenido:", data);
|
|
if (!data || !data.ID_Producto) {
|
|
alert("Producto no encontrado.");
|
|
return;
|
|
}
|
|
|
|
const stockDisponible = parseInt(data.Stock_Disponible);
|
|
|
|
// Calculamos cuánto de este producto ya tenemos en la lista actual
|
|
const cantidadEnLista = productos
|
|
.filter((p) => p.id === data.ID_Producto)
|
|
.reduce((acc, p) => acc + p.cantidad, 0);
|
|
|
|
const cantidadTotalIntentada = cantidad + cantidadEnLista;
|
|
|
|
if (cantidadTotalIntentada > stockDisponible) {
|
|
alert(`Stock insuficiente.
|
|
Disponible: ${stockDisponible} unidades.
|
|
En lista: ${cantidadEnLista} unidades.
|
|
No puedes agregar ${cantidad} más.`);
|
|
return;
|
|
}
|
|
|
|
const precio = parseFloat(data.Precio_Venta);
|
|
const subtotal = precio * cantidad;
|
|
|
|
productos.push({
|
|
id: data.ID_Producto,
|
|
descripcion: data.Descripcion,
|
|
precio: precio,
|
|
cantidad: cantidad,
|
|
subtotal: subtotal,
|
|
stockMaximo: stockDisponible,
|
|
});
|
|
|
|
actualizarTabla();
|
|
codigoInput.value = "";
|
|
nombreInput.value = "";
|
|
cantidadInput.value = "";
|
|
})
|
|
.catch((error) => {
|
|
console.error("Error al buscar el producto:", error);
|
|
});
|
|
});
|
|
|
|
btnRegistrar.addEventListener("click", () => {
|
|
if (productos.length === 0) {
|
|
alert("No hay productos agregados.");
|
|
return;
|
|
}
|
|
|
|
fetch("../php/Registrar_Venta.php", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(productos),
|
|
})
|
|
.then((res) => res.text())
|
|
.then((msg) => {
|
|
alert(msg);
|
|
productos.length = 0;
|
|
actualizarTabla();
|
|
if (typeof window.verificarStockBajoMenu === 'function') {
|
|
window.verificarStockBajoMenu();
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error("Error al registrar la venta:", err);
|
|
});
|
|
});
|
|
});
|
|
|
|
function actualizarTabla() {
|
|
const tbody = document.querySelector("#tabla-ventas tbody");
|
|
tbody.innerHTML = "";
|
|
|
|
let total = 0;
|
|
|
|
productos.forEach((p, index) => {
|
|
total += p.subtotal;
|
|
|
|
const fila = document.createElement("tr");
|
|
fila.innerHTML = `
|
|
<td>${p.id}</td>
|
|
<td>${p.descripcion}</td>
|
|
<td>$${p.precio.toFixed(2)}</td>
|
|
<td>${p.cantidad}</td>
|
|
<td>$${p.subtotal.toFixed(2)}</td>
|
|
<td>
|
|
<button class="btn-eliminar" onclick="eliminarProductoVenta(${index})">Eliminar</button>
|
|
</td>
|
|
`;
|
|
tbody.appendChild(fila);
|
|
});
|
|
|
|
document.getElementById("total").value = `$${total.toFixed(2)}`;
|
|
}
|
|
|
|
function eliminarProductoVenta(index) {
|
|
productos.splice(index, 1);
|
|
actualizarTabla();
|
|
}
|