430 lines
14 KiB
JavaScript
430 lines
14 KiB
JavaScript
const productosOrden = [];
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const codigoProveedor = document.getElementById("codigo-proveedor");
|
|
const nombreProveedor = document.getElementById("nombre-proveedor");
|
|
const telefonoProveedor = document.getElementById("telefono-proveedor");
|
|
const codigoProducto = document.getElementById("codigo-producto");
|
|
const cantidadProducto = document.getElementById("cantidad-producto");
|
|
const btnAgregar = document.getElementById("btn-agregar-producto");
|
|
const btnGenerar = document.getElementById("btn-generar-orden");
|
|
const tabla = document.querySelector("#tabla-orden tbody");
|
|
const tablaOrdenes = document.querySelector("#tabla-ordenes tbody");
|
|
|
|
let ordenDetalleActual = null;
|
|
let modoEdicionDetalle = false;
|
|
|
|
if (codigoProveedor) {
|
|
codigoProveedor.addEventListener("blur", () => {
|
|
fetch(`../php/Buscar_Proveedor.php?codigo=${codigoProveedor.value.trim()}`)
|
|
.then((res) => res.json())
|
|
.then((data) => {
|
|
if (data && data.Nombre && data.Telefono) {
|
|
nombreProveedor.value = data.Nombre;
|
|
telefonoProveedor.value = data.Telefono;
|
|
} else {
|
|
nombreProveedor.value = "";
|
|
telefonoProveedor.value = "";
|
|
alert("Proveedor no encontrado.");
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
if (btnAgregar) {
|
|
btnAgregar.addEventListener("click", () => {
|
|
const codigo = codigoProducto.value.trim();
|
|
const cantidad = parseInt(cantidadProducto.value, 10);
|
|
|
|
if (!codigo || cantidad <= 0) {
|
|
alert("Código y cantidad válidos requeridos.");
|
|
return;
|
|
}
|
|
|
|
fetch(`../php/Buscar_Producto_Orden.php?codigo=${codigo}`)
|
|
.then((res) => {
|
|
if (!res.ok) {
|
|
throw new Error("Error en la solicitud al servidor.");
|
|
}
|
|
return res.json();
|
|
})
|
|
.then((producto) => {
|
|
if (!producto || !producto.ID_Producto) {
|
|
alert("Producto no encontrado.");
|
|
return;
|
|
}
|
|
|
|
productosOrden.push({
|
|
id: producto.ID_Producto,
|
|
descripcion: producto.Descripcion,
|
|
cantidad: cantidad,
|
|
});
|
|
|
|
actualizarTabla();
|
|
codigoProducto.value = "";
|
|
cantidadProducto.value = "";
|
|
})
|
|
.catch((err) => {
|
|
console.error("Error al obtener el producto:", err);
|
|
});
|
|
});
|
|
}
|
|
|
|
if (btnGenerar) {
|
|
btnGenerar.addEventListener("click", () => {
|
|
if (!codigoProveedor.value || productosOrden.length === 0) {
|
|
alert("Proveedor y al menos un producto son necesarios.");
|
|
return;
|
|
}
|
|
|
|
fetch("../php/Registrar_Orden_Compra.php", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
proveedor: codigoProveedor.value,
|
|
productos: productosOrden,
|
|
}),
|
|
})
|
|
.then((res) => res.text())
|
|
.then((msg) => {
|
|
alert(msg);
|
|
productosOrden.length = 0;
|
|
actualizarTabla();
|
|
document.getElementById("form-orden").reset();
|
|
cargarOrdenesCompra();
|
|
});
|
|
});
|
|
}
|
|
|
|
function actualizarTabla() {
|
|
if (!tabla) return;
|
|
tabla.innerHTML = "";
|
|
productosOrden.forEach((p, i) => {
|
|
const fila = document.createElement("tr");
|
|
fila.innerHTML = `
|
|
<td>${p.id}</td>
|
|
<td>${p.descripcion}</td>
|
|
<td>${p.cantidad}</td>
|
|
<td>
|
|
<button type="button" class="btn-eliminar" onclick="eliminarProductoOrden(${i})">Eliminar</button>
|
|
</td>
|
|
`;
|
|
tabla.appendChild(fila);
|
|
});
|
|
}
|
|
|
|
function cargarOrdenesCompra() {
|
|
if (!tablaOrdenes) return;
|
|
fetch("../php/Obtener_Ordenes_Compra.php")
|
|
.then((res) => res.json())
|
|
.then((ordenes) => {
|
|
tablaOrdenes.innerHTML = "";
|
|
ordenes.forEach((orden) => {
|
|
const fila = document.createElement("tr");
|
|
const estadoNumerico = parseInt(orden.Estado, 10);
|
|
const estaProcesada = estadoNumerico !== 0;
|
|
|
|
let textoEstado = "Pendiente";
|
|
if (estadoNumerico === 1) textoEstado = "Aprobada";
|
|
if (estadoNumerico === 2) textoEstado = "Denegada";
|
|
if (estadoNumerico === 3) textoEstado = "Confirmada";
|
|
|
|
fila.innerHTML = `
|
|
<td>${orden.ID_Orden}</td>
|
|
<td>${orden.Fecha}</td>
|
|
<td>${orden.ID_Proveedor || "N/A"}</td>
|
|
<td>${orden.Proveedor || "Sin nombre"}</td>
|
|
<td>${orden.Telefono || "Sin registrar"}</td>
|
|
<td>${textoEstado}</td>
|
|
<td>
|
|
<button type="button" class="btn-ver-orden" data-id="${orden.ID_Orden}" data-estado="${orden.Estado || 0}">Ver Orden</button>
|
|
<button type="button" class="btn-aprobar"
|
|
data-id="${orden.ID_Orden}"
|
|
data-telefono="${orden.Telefono || ''}"
|
|
data-proveedor="${orden.Proveedor || ''}"
|
|
${estaProcesada ? "disabled" : ""}>Aprobar</button>
|
|
<button type="button" class="btn-denegar"
|
|
data-id="${orden.ID_Orden}"
|
|
${estaProcesada ? "disabled" : ""}>Denegar</button>
|
|
</td>
|
|
`;
|
|
tablaOrdenes.appendChild(fila);
|
|
});
|
|
|
|
tablaOrdenes.querySelectorAll(".btn-aprobar").forEach((btn) => {
|
|
btn.addEventListener("click", () => {
|
|
cambiarEstadoOrden(btn.dataset.id, true, btn.dataset.telefono, btn.dataset.proveedor);
|
|
});
|
|
});
|
|
|
|
tablaOrdenes.querySelectorAll(".btn-denegar").forEach((btn) => {
|
|
btn.addEventListener("click", () => cambiarEstadoOrden(btn.dataset.id, false));
|
|
});
|
|
|
|
tablaOrdenes.querySelectorAll(".btn-ver-orden").forEach((btn) => {
|
|
btn.addEventListener("click", () => verProductosOrden(btn.dataset.id, btn.dataset.estado));
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
console.error("Error al cargar órdenes de compra:", err);
|
|
});
|
|
}
|
|
|
|
function cambiarEstadoOrden(idOrden, esAprobacion, telefono = "", nombreProv = "") {
|
|
const nuevoEstado = esAprobacion ? 1 : 2;
|
|
|
|
fetch("../php/Actualizar_Orden_Compra.php", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ id: parseInt(idOrden, 10), estado: nuevoEstado }),
|
|
})
|
|
.then(async (res) => {
|
|
const text = await res.text();
|
|
if (!res.ok) {
|
|
throw new Error(text || `HTTP ${res.status}`);
|
|
}
|
|
try {
|
|
return JSON.parse(text);
|
|
} catch (jsonErr) {
|
|
throw new Error(`Respuesta inválida del servidor: ${text}`);
|
|
}
|
|
})
|
|
.then((data) => {
|
|
if (data.success) {
|
|
if (esAprobacion && telefono) {
|
|
enviarOrdenPorWhatsApp(idOrden, telefono, nombreProv);
|
|
}
|
|
cargarOrdenesCompra();
|
|
} else {
|
|
alert("Error: " + (data.error || "No se pudo actualizar"));
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error("Error al actualizar la orden:", err);
|
|
alert("Error al actualizar la orden: " + err.message);
|
|
});
|
|
}
|
|
|
|
function enviarOrdenPorWhatsApp(idOrden, telefono, nombreProv) {
|
|
const telefonoLimpio = telefono.replace(/[^0-9]/g, "");
|
|
|
|
fetch(`../php/Obtener_Productos_Orden.php?id=${idOrden}`)
|
|
.then((res) => res.json())
|
|
.then((productos) => {
|
|
let mensaje = `*Orden de Compra #${idOrden}*\n`;
|
|
mensaje += `Proveedor: ${nombreProv}\n`;
|
|
mensaje += `--------------------------\n`;
|
|
|
|
productos.forEach((p) => {
|
|
mensaje += `- ${p.Cantidad} x ${p.Descripcion}\n`;
|
|
});
|
|
|
|
mensaje += `--------------------------\n`;
|
|
mensaje += `Favor de confirmar recepción.`;
|
|
|
|
const mensajeUrl = encodeURIComponent(mensaje);
|
|
const urlWhatsApp = `https://web.whatsapp.com/send?phone=${telefonoLimpio}&text=${mensajeUrl}`;
|
|
|
|
window.open(urlWhatsApp, "_blank");
|
|
})
|
|
.catch((err) => console.error("Error al obtener productos para WhatsApp:", err));
|
|
}
|
|
|
|
function renderDetalleOrden() {
|
|
const cuerpo = document.getElementById("productos-orden-body");
|
|
if (!cuerpo || !ordenDetalleActual) {
|
|
return;
|
|
}
|
|
|
|
cuerpo.innerHTML = "";
|
|
|
|
if (ordenDetalleActual.productos.length === 0) {
|
|
const filaVacia = document.createElement("tr");
|
|
filaVacia.innerHTML = '<td colspan="2">No hay productos registrados.</td>';
|
|
cuerpo.appendChild(filaVacia);
|
|
actualizarBotonesDetalleOrden();
|
|
return;
|
|
}
|
|
|
|
ordenDetalleActual.productos.forEach((prod) => {
|
|
const fila = document.createElement("tr");
|
|
const cantidadActual = prod.Cantidad || 0;
|
|
const celdaCantidad = modoEdicionDetalle
|
|
? `<td><input type="number" min="1" value="${cantidadActual}" data-product-id="${prod.ID_Producto}" class="input-cantidad-orden" /></td>`
|
|
: `<td>${cantidadActual}</td>`;
|
|
|
|
fila.innerHTML = `
|
|
<td>${prod.Descripcion}</td>
|
|
${celdaCantidad}
|
|
`;
|
|
cuerpo.appendChild(fila);
|
|
});
|
|
|
|
actualizarBotonesDetalleOrden();
|
|
}
|
|
|
|
function actualizarBotonesDetalleOrden() {
|
|
const btnConfirmar = document.getElementById("btn-confirmar-recepcion");
|
|
const btnEditar = document.getElementById("btn-editar-orden");
|
|
const btnGuardar = document.getElementById("btn-guardar-orden");
|
|
const btnCancelar = document.getElementById("btn-cancelar-orden");
|
|
const btnCerrar = document.getElementById("cerrar-orden");
|
|
|
|
if (!btnConfirmar || !btnEditar || !btnGuardar || !btnCancelar || !btnCerrar) {
|
|
return;
|
|
}
|
|
|
|
const estado = parseInt(ordenDetalleActual?.estado || 0, 10);
|
|
const esConfirmada = estado === 3;
|
|
const esBloqueada = estado === 2 || estado === 3;
|
|
|
|
if (modoEdicionDetalle) {
|
|
btnConfirmar.style.display = "none";
|
|
btnEditar.style.display = "none";
|
|
btnCerrar.style.display = "none";
|
|
btnGuardar.style.display = "inline-block";
|
|
btnCancelar.style.display = "inline-block";
|
|
} else {
|
|
btnConfirmar.style.display = "inline-block";
|
|
btnEditar.style.display = "inline-block";
|
|
btnCerrar.style.display = "inline-block";
|
|
btnGuardar.style.display = "none";
|
|
btnCancelar.style.display = "none";
|
|
}
|
|
|
|
btnConfirmar.disabled = esConfirmada || esBloqueada;
|
|
btnEditar.disabled = esConfirmada || esBloqueada;
|
|
}
|
|
|
|
function verProductosOrden(idOrden, estadoActual = 0) {
|
|
fetch(`../php/Obtener_Productos_Orden.php?id=${idOrden}`)
|
|
.then((res) => res.json())
|
|
.then((productos) => {
|
|
ordenDetalleActual = {
|
|
id: parseInt(idOrden, 10),
|
|
estado: parseInt(estadoActual, 10),
|
|
productos: productos || [],
|
|
};
|
|
modoEdicionDetalle = false;
|
|
renderDetalleOrden();
|
|
|
|
document.getElementById("tabla-ordenes").style.display = "none";
|
|
document.getElementById("productos-orden").style.display = "block";
|
|
})
|
|
.catch((err) => {
|
|
console.error("Error al cargar productos de la orden:", err);
|
|
});
|
|
}
|
|
|
|
async function confirmarRecepcionOrden() {
|
|
if (!ordenDetalleActual) return;
|
|
|
|
try {
|
|
const res = await fetch("../php/Actualizar_Orden_Compra.php", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ id: ordenDetalleActual.id, estado: 3 }),
|
|
});
|
|
const data = await res.json();
|
|
|
|
if (data.success) {
|
|
ordenDetalleActual.estado = 3;
|
|
cargarOrdenesCompra();
|
|
if (window.cargarProductos) {
|
|
window.cargarProductos();
|
|
}
|
|
renderDetalleOrden();
|
|
} else {
|
|
alert("Error: " + (data.error || "No se pudo confirmar la recepción"));
|
|
}
|
|
} catch (err) {
|
|
console.error("Error al confirmar recepción:", err);
|
|
}
|
|
}
|
|
|
|
function activarEdicionDetalleOrden() {
|
|
modoEdicionDetalle = true;
|
|
renderDetalleOrden();
|
|
}
|
|
|
|
function cancelarEdicionDetalleOrden() {
|
|
modoEdicionDetalle = false;
|
|
renderDetalleOrden();
|
|
}
|
|
|
|
async function guardarEdicionDetalleOrden() {
|
|
if (!ordenDetalleActual) return;
|
|
|
|
const productosActualizados = ordenDetalleActual.productos.map((prod) => {
|
|
const input = document.querySelector(`input[data-product-id="${prod.ID_Producto}"]`);
|
|
const cantidad = input ? parseInt(input.value, 10) : parseInt(prod.Cantidad, 10);
|
|
|
|
if (!Number.isInteger(cantidad) || cantidad < 1) {
|
|
throw new Error(`La cantidad para ${prod.Descripcion} debe ser un número mayor a 0.`);
|
|
}
|
|
|
|
return {
|
|
...prod,
|
|
Cantidad: cantidad,
|
|
};
|
|
});
|
|
|
|
try {
|
|
const res = await fetch("../php/Actualizar_Productos_Orden.php", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
id: ordenDetalleActual.id,
|
|
productos: productosActualizados.map((prod) => ({
|
|
id: prod.ID_Producto,
|
|
cantidad: prod.Cantidad,
|
|
})),
|
|
}),
|
|
});
|
|
const data = await res.json();
|
|
|
|
if (data.success) {
|
|
ordenDetalleActual.productos = productosActualizados;
|
|
modoEdicionDetalle = false;
|
|
renderDetalleOrden();
|
|
} else {
|
|
alert("Error: " + (data.error || "No se pudieron guardar los cambios"));
|
|
}
|
|
} catch (err) {
|
|
console.error("Error al guardar edición:", err);
|
|
alert(err.message || "Ocurrió un error al guardar los cambios.");
|
|
}
|
|
}
|
|
|
|
cargarOrdenesCompra();
|
|
|
|
document.getElementById("cerrar-orden").addEventListener("click", () => {
|
|
document.getElementById("tabla-ordenes").style.display = "table";
|
|
document.getElementById("productos-orden").style.display = "none";
|
|
ordenDetalleActual = null;
|
|
modoEdicionDetalle = false;
|
|
});
|
|
|
|
document.getElementById("btn-confirmar-recepcion").addEventListener("click", confirmarRecepcionOrden);
|
|
document.getElementById("btn-editar-orden").addEventListener("click", activarEdicionDetalleOrden);
|
|
document.getElementById("btn-guardar-orden").addEventListener("click", guardarEdicionDetalleOrden);
|
|
document.getElementById("btn-cancelar-orden").addEventListener("click", cancelarEdicionDetalleOrden);
|
|
});
|
|
|
|
function eliminarProductoOrden(index) {
|
|
productosOrden.splice(index, 1);
|
|
document.querySelector("#tabla-orden tbody").innerHTML = "";
|
|
productosOrden.forEach((p, i) => {
|
|
const fila = document.createElement("tr");
|
|
fila.innerHTML = `
|
|
<td>${p.id}</td>
|
|
<td>${p.descripcion}</td>
|
|
<td>${p.cantidad}</td>
|
|
<td>
|
|
<button type="button" onclick="eliminarProductoOrden(${i})">Eliminar</button>
|
|
</td>
|
|
`;
|
|
document.querySelector("#tabla-orden tbody").appendChild(fila);
|
|
});
|
|
}
|