-
\ No newline at end of file
+
diff --git a/pedidos.php b/pedidos.php
index 20c9e35..1b987be 100644
--- a/pedidos.php
+++ b/pedidos.php
@@ -155,6 +155,7 @@ include 'layout_header.php';
Celular
Producto
Sede de Envío
+
Cantidad
Monto Total
Monto Debe
Nº De Orden
@@ -176,6 +177,7 @@ include 'layout_header.php';
+
diff --git a/registrar_entrada_manual_api.php b/registrar_entrada_manual_api.php
new file mode 100644
index 0000000..6cb83df
--- /dev/null
+++ b/registrar_entrada_manual_api.php
@@ -0,0 +1,62 @@
+ false, 'message' => 'Petición inválida.'];
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $sede_id = isset($_POST['sede_id']) ? filter_var($_POST['sede_id'], FILTER_VALIDATE_INT) : null;
+ $product_id = isset($_POST['product_id']) ? filter_var($_POST['product_id'], FILTER_VALIDATE_INT) : null;
+ $cantidad = isset($_POST['cantidad']) ? filter_var($_POST['cantidad'], FILTER_VALIDATE_INT) : null;
+
+ if (!$sede_id || !$product_id || !$cantidad || $cantidad <= 0) {
+ $response['message'] = 'Datos inválidos. Por favor, complete todos los campos correctamente.';
+ echo json_encode($response);
+ exit;
+ }
+
+ try {
+ $pdo = db();
+ $pdo->beginTransaction();
+
+ // 1. Actualizar o insertar en stock_sedes
+ $sql_stock = "INSERT INTO stock_sedes (id_producto, id_sede, cantidad)
+ VALUES (:product_id, :sede_id, :cantidad)
+ ON DUPLICATE KEY UPDATE cantidad = cantidad + :cantidad";
+
+ $stmt_stock = $pdo->prepare($sql_stock);
+ $stmt_stock->bindParam(':product_id', $product_id, PDO::PARAM_INT);
+ $stmt_stock->bindParam(':sede_id', $sede_id, PDO::PARAM_INT);
+ $stmt_stock->bindParam(':cantidad', $cantidad, PDO::PARAM_INT);
+ $stmt_stock->execute();
+
+ // 2. Registrar el movimiento
+ $sql_movement = "INSERT INTO stock_movements (product_id, sede_id, tipo_movimiento, cantidad, origen)
+ VALUES (:product_id, :sede_id, 'entrada', :cantidad, 'manual')";
+
+ $stmt_movement = $pdo->prepare($sql_movement);
+ $stmt_movement->bindParam(':product_id', $product_id, PDO::PARAM_INT);
+ $stmt_movement->bindParam(':sede_id', $sede_id, PDO::PARAM_INT);
+ $stmt_movement->bindParam(':cantidad', $cantidad, PDO::PARAM_INT);
+ $stmt_movement->execute();
+
+ $pdo->commit();
+
+ $response['success'] = true;
+ $response['message'] = "Se han añadido {$cantidad} unidades al stock correctamente.";
+
+ } catch (PDOException $e) {
+ if ($pdo->inTransaction()) {
+ $pdo->rollBack();
+ }
+ // Log del error para depuración, no mostrar al usuario final
+ error_log("Error en registrar_entrada_manual_api.php: " . $e->getMessage());
+ $response['message'] = 'Error en la base de datos. No se pudo registrar la entrada.';
+ }
+
+} else {
+ $response['message'] = 'Método no permitido.';
+}
+
+echo json_encode($response);
+?>
diff --git a/registrar_salida_manual_api.php b/registrar_salida_manual_api.php
index 4c3a106..cc3959c 100644
--- a/registrar_salida_manual_api.php
+++ b/registrar_salida_manual_api.php
@@ -5,72 +5,70 @@ require_once 'db/config.php';
$response = ['success' => false, 'message' => 'Petición inválida.'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- $sede_id = isset($_POST['sede_id']) ? trim($_POST['sede_id']) : '';
- $product_id_raw = isset($_POST['product_id']) ? trim($_POST['product_id']) : '';
- $quantity_to_remove = isset($_POST['quantity']) ? (int)$_POST['quantity'] : 0;
+ $sede_id = isset($_POST['sede_id']) ? filter_var($_POST['sede_id'], FILTER_VALIDATE_INT) : null;
+ $product_id = isset($_POST['product_id']) ? filter_var($_POST['product_id'], FILTER_VALIDATE_INT) : null;
+ $quantity = isset($_POST['quantity']) ? filter_var($_POST['quantity'], FILTER_VALIDATE_INT) : null;
- // Extraer el ID numérico del producto
- $product_id_parts = explode('-', $product_id_raw);
- $product_id = end($product_id_parts);
-
- if (empty($sede_id) || !is_numeric($product_id) || $quantity_to_remove <= 0) {
- $response['message'] = 'Por favor, complete todos los campos correctamente.';
+ if (!$sede_id || !$product_id || !$quantity || $quantity <= 0) {
+ $response['message'] = 'Datos inválidos. Por favor, complete todos los campos correctamente.';
echo json_encode($response);
exit;
}
- $pdo = db();
- $pdo->beginTransaction();
-
try {
- // 1. Obtener el stock actual y bloquear la fila para evitar concurrencia
- $stmt = $pdo->prepare("SELECT quantity FROM stock_sedes WHERE sede_id = :sede_id AND product_id = :product_id FOR UPDATE");
- $stmt->execute(['sede_id' => $sede_id, 'product_id' => $product_id]);
- $stock = $stmt->fetch(PDO::FETCH_ASSOC);
+ $pdo = db();
+ $pdo->beginTransaction();
- $current_quantity = $stock ? (int)$stock['quantity'] : 0;
+ // 1. Verificar stock actual
+ $sql_check = "SELECT cantidad FROM stock_sedes WHERE id_producto = :product_id AND id_sede = :sede_id FOR UPDATE";
+ $stmt_check = $pdo->prepare($sql_check);
+ $stmt_check->bindParam(':product_id', $product_id, PDO::PARAM_INT);
+ $stmt_check->bindParam(':sede_id', $sede_id, PDO::PARAM_INT);
+ $stmt_check->execute();
+ $current_stock_row = $stmt_check->fetch(PDO::FETCH_ASSOC);
- if ($current_quantity < $quantity_to_remove) {
- $response['message'] = "No se puede retirar más stock del disponible. Stock actual: {$current_quantity}.";
+ $current_stock = $current_stock_row ? (int)$current_stock_row['cantidad'] : 0;
+
+ if ($current_stock < $quantity) {
+ $response['message'] = "Stock insuficiente. Stock actual: {$current_stock} unidades.";
$pdo->rollBack();
echo json_encode($response);
exit;
}
- // 2. Calcular la nueva cantidad
- $new_quantity = $current_quantity - $quantity_to_remove;
+ // 2. Actualizar stock_sedes
+ $sql_update = "UPDATE stock_sedes SET cantidad = cantidad - :quantity WHERE id_producto = :product_id AND id_sede = :sede_id";
+ $stmt_update = $pdo->prepare($sql_update);
+ $stmt_update->bindParam(':quantity', $quantity, PDO::PARAM_INT);
+ $stmt_update->bindParam(':product_id', $product_id, PDO::PARAM_INT);
+ $stmt_update->bindParam(':sede_id', $sede_id, PDO::PARAM_INT);
+ $stmt_update->execute();
- // 3. Actualizar la tabla de stock
- $update_stmt = $pdo->prepare(
- "UPDATE stock_sedes SET quantity = :new_quantity WHERE sede_id = :sede_id AND product_id = :product_id"
- );
- $update_stmt->execute([
- 'new_quantity' => $new_quantity,
- 'sede_id' => $sede_id,
- 'product_id' => $product_id
- ]);
-
- // 4. (Opcional pero recomendado) Registrar el movimiento
- $movement_stmt = $pdo->prepare(
- "INSERT INTO stock_movements (product_id, sede_id, quantity, type, movement_date) VALUES (:product_id, :sede_id, :quantity, 'salida', NOW())"
- );
- $movement_stmt->execute([
- 'product_id' => $product_id,
- 'sede_id' => $sede_id,
- 'quantity' => $quantity_to_remove
- ]);
+ // 3. Registrar el movimiento
+ $sql_movement = "INSERT INTO stock_movements (product_id, sede_id, tipo_movimiento, cantidad, origen)
+ VALUES (:product_id, :sede_id, 'salida', :quantity, 'manual')";
+ $stmt_movement = $pdo->prepare($sql_movement);
+ $stmt_movement->bindParam(':product_id', $product_id, PDO::PARAM_INT);
+ $stmt_movement->bindParam(':sede_id', $sede_id, PDO::PARAM_INT);
+ $stmt_movement->bindParam(':quantity', $quantity, PDO::PARAM_INT);
+ $stmt_movement->execute();
$pdo->commit();
+
$response['success'] = true;
- $response['message'] = "Salida manual registrada con éxito. Stock actualizado a {$new_quantity} unidades.";
+ $response['message'] = "Se han retirado {$quantity} unidades del stock correctamente.";
} catch (PDOException $e) {
- $pdo->rollBack();
- // En un entorno de producción, no deberías exponer el mensaje de error detallado.
- // Considera registrar el error en un archivo de logs.
- $response['message'] = 'Error en la base de datos al procesar la solicitud.'; // Mensaje genérico para el usuario
+ if ($pdo->inTransaction()) {
+ $pdo->rollBack();
+ }
+ error_log("Error en registrar_salida_manual_api.php: " . $e->getMessage());
+ $response['message'] = 'Error en la base de datos. No se pudo registrar la salida.';
}
+
+} else {
+ $response['message'] = 'Método no permitido.';
}
echo json_encode($response);
-?>
\ No newline at end of file
+?>
diff --git a/registro_entrada.php b/registro_entrada.php
index 18e71d8..a8937a2 100644
--- a/registro_entrada.php
+++ b/registro_entrada.php
@@ -1,24 +1,30 @@
query("SELECT id, nombre FROM sedes ORDER BY nombre ASC");
$sedes = $sedes_stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ // Obtener productos
+ $products_stmt = $pdo->query("SELECT id, nombre FROM products ORDER BY nombre ASC");
+ $products = $products_stmt->fetchAll(PDO::FETCH_ASSOC);
+
} catch (PDOException $e) {
- $error_page_load = "Error al cargar las sedes: " . $e->getMessage();
+ $error_page_load = "Error al cargar datos iniciales: " . $e->getMessage();
}
?>
-
+
@@ -31,39 +37,88 @@ try {
- Registro de Entrada por Unidad
+
-
@@ -92,18 +147,20 @@ try {
-
+
\ No newline at end of file
diff --git a/registro_salida.php b/registro_salida.php
index 9b2b2fb..08c49be 100644
--- a/registro_salida.php
+++ b/registro_salida.php
@@ -1,19 +1,20 @@
query("SELECT id, nombre FROM sedes ORDER BY nombre ASC");
$sedes = $sedes_stmt->fetchAll(PDO::FETCH_ASSOC);
-
- // Encontrar el ID de "ALMACEN PRINCIPAL" para usarlo en el script
+
+ // Encontrar el ID de "ALMACEN PRINCIPAL" para la lógica móvil
foreach ($sedes as $sede) {
if (trim(strtolower($sede['nombre'])) === 'almacen principal') {
$almacen_principal_id = $sede['id'];
@@ -21,23 +22,18 @@ try {
}
}
-} catch (PDOException $e) {
- $error_page_load = "Error al cargar datos: " . $e->getMessage();
-}
-
-// Obtener productos para el dropdown manual
-$products = [];
-try {
+ // Obtener productos
$products_stmt = $pdo->query("SELECT id, nombre, sku FROM products ORDER BY nombre ASC");
$products = $products_stmt->fetchAll(PDO::FETCH_ASSOC);
+
} catch (PDOException $e) {
- $error_page_load .= " Error al cargar productos: " . $e->getMessage();
+ $error_page_load = "Error al cargar datos iniciales: " . $e->getMessage();
}
?>
-
+
@@ -50,75 +46,89 @@ try {
- Escanear Código de Barras
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
-
-
-
- Salida Manual de Stock
-
-
-
Utilice este formulario para ajustar el inventario y poner en cero el stock de productos antiguos o sin SKU.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -145,38 +155,35 @@ try {
-
+
\ No newline at end of file