1ra Versión
This commit is contained in:
@@ -0,0 +1,429 @@
|
||||
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);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user