Autosave: 20260610-161940

This commit is contained in:
Flatlogic Bot 2026-06-10 16:19:28 +00:00
parent 3f9d04425f
commit 7da0c2905a
9 changed files with 264 additions and 35 deletions

View File

@ -13,15 +13,23 @@ if (!isset($_SESSION['user_id']) || !in_array($_SESSION['user_role'], ['Administ
$db = db(); $db = db();
// --- LÓGICA DE FILTROS --- // --- LÓGICA DE FILTROS ---
$period = $_GET['period'] ?? '7'; $period = $_GET['period'] ?? 'today';
$start_date = $_GET['start_date'] ?? ''; $start_date = trim((string)($_GET['start_date'] ?? ''));
$end_date = $_GET['end_date'] ?? ''; $end_date = trim((string)($_GET['end_date'] ?? ''));
$isValidDashboardDate = static function (string $date): bool {
$parsed = DateTimeImmutable::createFromFormat('Y-m-d', $date);
return $parsed instanceof DateTimeImmutable && $parsed->format('Y-m-d') === $date;
};
$date_condition = ""; $date_condition = "";
$label_period = ""; $label_period = "";
if ($period === 'custom' && !empty($start_date) && !empty($end_date)) { if ($period === 'custom' && $isValidDashboardDate($start_date) && $isValidDashboardDate($end_date)) {
$date_condition = "DATE(p.created_at) BETWEEN '$start_date' AND '$end_date'"; if ($start_date > $end_date) {
[$start_date, $end_date] = [$end_date, $start_date];
}
$date_condition = "DATE(p.created_at) BETWEEN " . $db->quote($start_date) . " AND " . $db->quote($end_date);
$label_period = "Desde " . date('d/m/Y', strtotime($start_date)) . " hasta " . date('d/m/Y', strtotime($end_date)); $label_period = "Desde " . date('d/m/Y', strtotime($start_date)) . " hasta " . date('d/m/Y', strtotime($end_date));
} else { } else {
switch ($period) { switch ($period) {
@ -66,9 +74,9 @@ if ($period === 'custom' && !empty($start_date) && !empty($end_date)) {
$label_period = "Último Año"; $label_period = "Último Año";
break; break;
default: default:
$date_condition = "DATE(p.created_at) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)"; $date_condition = "DATE(p.created_at) = CURDATE()";
$label_period = "Últimos 7 días"; $label_period = "Hoy";
$period = '7'; $period = 'today';
} }
} }

View File

@ -0,0 +1,3 @@
-- Deprecated/no-op.
-- PENDIENTE belongs to pedidos.estado, not to pedidos.tipo_paquete.
-- The final package ENUM is enforced in 078_clean_tipo_paquete_enum.sql.

View File

@ -0,0 +1,4 @@
-- Keep pedidos.tipo_paquete aligned with the package selector.
-- PENDIENTE belongs to pedidos.estado, not to tipo_paquete.
UPDATE pedidos SET tipo_paquete = NULL WHERE tipo_paquete = 'PENDIENTE';
ALTER TABLE pedidos MODIFY COLUMN tipo_paquete ENUM('RUTA', 'CONTRAENTREGA', 'NO CONTESTA, VOLVER A LLAMAR', 'PENDIENTE A RETORNO', 'COMPLETADO', 'EMPAQUETADO', 'RETORNADO', 'ANULADO') DEFAULT NULL;

View File

@ -0,0 +1,5 @@
-- Rename package status EMPAQUETADO to PREPARADO in pedidos.tipo_paquete.
-- EMPAQUETADO is kept only as a temporary legacy value during migration so existing rows can be converted safely.
ALTER TABLE pedidos MODIFY COLUMN tipo_paquete ENUM('RUTA', 'CONTRAENTREGA', 'NO CONTESTA, VOLVER A LLAMAR', 'PENDIENTE A RETORNO', 'COMPLETADO', 'EMPAQUETADO', 'PREPARADO', 'RETORNADO', 'ANULADO') DEFAULT NULL;
UPDATE pedidos SET tipo_paquete = 'PREPARADO' WHERE tipo_paquete = 'EMPAQUETADO';
ALTER TABLE pedidos MODIFY COLUMN tipo_paquete ENUM('RUTA', 'CONTRAENTREGA', 'NO CONTESTA, VOLVER A LLAMAR', 'PENDIENTE A RETORNO', 'COMPLETADO', 'PREPARADO', 'RETORNADO', 'ANULADO') DEFAULT NULL;

136
includes/tipo_paquete.php Normal file
View File

@ -0,0 +1,136 @@
<?php
if (!function_exists('tipoPaqueteValidValues')) {
function tipoPaqueteValidValues(): array
{
return [
'RUTA',
'CONTRAENTREGA',
'NO CONTESTA, VOLVER A LLAMAR',
'PENDIENTE A RETORNO',
'COMPLETADO',
'PREPARADO',
'RETORNADO',
'ANULADO',
];
}
}
if (!function_exists('tipoPaquetePrimarySelectorValues')) {
function tipoPaquetePrimarySelectorValues(): array
{
return [
'PREPARADO',
'RUTA',
'ANULADO',
'PENDIENTE A RETORNO',
'RETORNADO',
'COMPLETADO',
];
}
}
if (!function_exists('normalizeTipoPaqueteValue')) {
function normalizeTipoPaqueteValue($value): ?string
{
if ($value === null || is_array($value)) {
return null;
}
$value = (string) $value;
$value = preg_replace('/[\x{00A0}\x{200B}-\x{200D}\x{FEFF}]+/u', ' ', $value);
$value = preg_replace('/[\x00-\x1F\x7F]+/u', ' ', $value);
$value = preg_replace('/\s+/u', ' ', trim($value));
if ($value === '') {
return null;
}
$normalized = function_exists('mb_strtoupper') ? mb_strtoupper($value, 'UTF-8') : strtoupper($value);
$match = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $normalized);
if ($match === false || $match === null || $match === '') {
$match = $normalized;
}
$canonicalKey = preg_replace('/[^A-Z]+/', '', strtoupper($match));
$aliases = [
'RUTA' => 'RUTA',
'CONTRAENTREGA' => 'CONTRAENTREGA',
'NOCONTESTAVOLVERALLAMAR' => 'NO CONTESTA, VOLVER A LLAMAR',
'PENDIENTEARETORNO' => 'PENDIENTE A RETORNO',
'COMPLETADO' => 'COMPLETADO',
'EMPAQUETADO' => 'PREPARADO',
'PREPARADO' => 'PREPARADO',
'EMPACADO' => 'PREPARADO',
'EMPAQUETARDO' => 'PREPARADO',
'RETORNADO' => 'RETORNADO',
'ANULADO' => 'ANULADO',
];
return $aliases[$canonicalKey] ?? $normalized;
}
}
if (!function_exists('tipoPaqueteIsValid')) {
function tipoPaqueteIsValid(?string $value): bool
{
return $value === null || in_array($value, tipoPaqueteValidValues(), true);
}
}
if (!function_exists('ensureTipoPaqueteEnumDefinition')) {
function ensureTipoPaqueteEnumDefinition(PDO $pdo, bool $force = false): void
{
static $checked = false;
if ($checked && !$force) {
return;
}
$stmt = $pdo->query("SHOW COLUMNS FROM pedidos LIKE 'tipo_paquete'");
$column = $stmt ? $stmt->fetch(PDO::FETCH_ASSOC) : false;
if (!$column || empty($column['Type'])) {
$checked = true;
return;
}
$currentType = (string) $column['Type'];
$validValues = tipoPaqueteValidValues();
$missingRequiredValue = false;
foreach ($validValues as $value) {
if (strpos($currentType, "'" . str_replace("'", "''", $value) . "'") === false) {
$missingRequiredValue = true;
break;
}
}
$hasLegacyPendiente = strpos($currentType, "'PENDIENTE'") !== false;
$hasLegacyEmpaquetado = strpos($currentType, "'EMPAQUETADO'") !== false;
if ($force || $missingRequiredValue || $hasLegacyPendiente || $hasLegacyEmpaquetado) {
$quotedValues = array_map(static function (string $value) use ($pdo): string {
return $pdo->quote($value);
}, $validValues);
$enumValuesSql = implode(', ', $quotedValues);
$transitionValues = array_values(array_unique(array_merge(
$validValues,
['EMPAQUETADO', 'PENDIENTE', 'NO CONTESTA', 'VOLVER A LLAMAR']
)));
$quotedTransitionValues = array_map(static function (string $value) use ($pdo): string {
return $pdo->quote($value);
}, $transitionValues);
$transitionValuesSql = implode(', ', $quotedTransitionValues);
$pdo->exec("ALTER TABLE pedidos MODIFY COLUMN tipo_paquete ENUM($transitionValuesSql) DEFAULT NULL");
$pdo->exec("UPDATE pedidos SET tipo_paquete = 'PREPARADO' WHERE tipo_paquete = 'EMPAQUETADO'");
$pdo->exec("UPDATE pedidos SET tipo_paquete = 'NO CONTESTA, VOLVER A LLAMAR' WHERE tipo_paquete IN ('NO CONTESTA', 'VOLVER A LLAMAR')");
$pdo->exec("UPDATE pedidos SET tipo_paquete = NULL WHERE tipo_paquete = 'PENDIENTE'");
$pdo->exec("UPDATE pedidos SET tipo_paquete = NULL WHERE tipo_paquete IS NOT NULL AND tipo_paquete NOT IN ($enumValuesSql)");
$pdo->exec("ALTER TABLE pedidos MODIFY COLUMN tipo_paquete ENUM($enumValuesSql) DEFAULT NULL");
}
$checked = true;
}
}

View File

@ -7,7 +7,9 @@ if (!isset($_SESSION['user_id'])) {
require_once 'db/config.php'; require_once 'db/config.php';
require_once 'includes/contraentrega_cobertura.php'; require_once 'includes/contraentrega_cobertura.php';
require_once 'includes/tipo_paquete.php';
$pdo = db(); $pdo = db();
ensureTipoPaqueteEnumDefinition($pdo);
$user_id = $_SESSION['user_id']; $user_id = $_SESSION['user_id'];
$user_role = $_SESSION['user_role'] ?? 'Asesor'; $user_role = $_SESSION['user_role'] ?? 'Asesor';
@ -320,7 +322,7 @@ include 'layout_header.php';
<option value="">Seleccionar</option> <option value="">Seleccionar</option>
<?php <?php
$current_paquete = $pedido['tipo_paquete'] ?? ''; $current_paquete = $pedido['tipo_paquete'] ?? '';
$paquetes = ['RUTA', 'EMPAQUETADO', 'ANULADO', 'PENDIENTE A RETORNO', 'RETORNADO']; $paquetes = tipoPaquetePrimarySelectorValues();
foreach ($paquetes as $paquete) { foreach ($paquetes as $paquete) {
$selected = ($current_paquete == $paquete) ? 'selected' : ''; $selected = ($current_paquete == $paquete) ? 'selected' : '';
echo "<option value='{$paquete}' {$selected}>" . htmlspecialchars($paquete) . "</option>"; echo "<option value='{$paquete}' {$selected}>" . htmlspecialchars($paquete) . "</option>";
@ -333,7 +335,7 @@ include 'layout_header.php';
<select class="form-select" id="estado" name="estado" required> <select class="form-select" id="estado" name="estado" required>
<?php <?php
$current_status = $pedido['estado'] ?? 'RUTA_CONTRAENTREGA'; $current_status = $pedido['estado'] ?? 'RUTA_CONTRAENTREGA';
$statuses = ['RUTA_CONTRAENTREGA', 'NO CONTESTO, VOLVER A LLAMAR', 'CANCELADO', 'REPROGRAMADO', 'ENTREGA EXITOSA']; $statuses = ['RUTA_CONTRAENTREGA', 'PENDIENTE', 'NO CONTESTO, VOLVER A LLAMAR', 'CANCELADO', 'REPROGRAMADO', 'ENTREGA EXITOSA'];
foreach ($statuses as $status) { foreach ($statuses as $status) {
$selected = ($current_status == $status) ? 'selected' : ''; $selected = ($current_status == $status) ? 'selected' : '';
echo "<option value='{$status}' {$selected}>" . htmlspecialchars($status) . "</option>"; echo "<option value='{$status}' {$selected}>" . htmlspecialchars($status) . "</option>";

View File

@ -6,6 +6,7 @@ if (!isset($_SESSION['user_id'])) {
} }
require_once 'db/config.php'; require_once 'db/config.php';
require_once __DIR__ . '/includes/tipo_paquete.php';
function getStatusStyle($status) { function getStatusStyle($status) {
$style = 'color: white;'; // Default text color $style = 'color: white;'; // Default text color
@ -64,7 +65,8 @@ function getPaqueteStyle($paquete) {
if ($paquete === 'NO CONTESTA, VOLVER A LLAMAR') return 'background-color: #fd7e14; color: white;'; // Orange if ($paquete === 'NO CONTESTA, VOLVER A LLAMAR') return 'background-color: #fd7e14; color: white;'; // Orange
if ($paquete === 'PENDIENTE A RETORNO') return 'background-color: #dc3545; color: white;'; // Red if ($paquete === 'PENDIENTE A RETORNO') return 'background-color: #dc3545; color: white;'; // Red
if ($paquete === 'COMPLETADO') return 'background-color: #198754; color: white;'; // Success green if ($paquete === 'COMPLETADO') return 'background-color: #198754; color: white;'; // Success green
if ($paquete === "EMPAQUETADO") return "background-color: #20c997; color: white;"; // Empaquetado if ($paquete === 'PREPARADO') return 'background-color: #20c997; color: white;'; // Preparado
if ($paquete === 'EMPAQUETADO') return 'background-color: #20c997; color: white;'; // Legacy alias
if ($paquete === 'RETORNADO') return 'background-color: #dc3545; color: white;'; // Same red as PENDIENTE A RETORNO if ($paquete === 'RETORNADO') return 'background-color: #dc3545; color: white;'; // Same red as PENDIENTE A RETORNO
if ($paquete === 'ANULADO') return 'background-color: #212529; color: white;'; // Dark if ($paquete === 'ANULADO') return 'background-color: #212529; color: white;'; // Dark
return 'background-color: #6c757d; color: white;'; // Secondary grey return 'background-color: #6c757d; color: white;'; // Secondary grey
@ -82,6 +84,7 @@ function getFechaEntregaStyle($fecha) {
} }
$pdo = db(); $pdo = db();
ensureTipoPaqueteEnumDefinition($pdo);
$user_id = $_SESSION['user_id']; $user_id = $_SESSION['user_id'];
$user_role = $_SESSION['user_role'] ?? 'Asesor'; $user_role = $_SESSION['user_role'] ?? 'Asesor';
@ -506,10 +509,38 @@ function getPaqueteStyleJS(paquete) {
if (paquete === 'PENDIENTE A RETORNO') return 'background-color: #dc3545; color: white;'; if (paquete === 'PENDIENTE A RETORNO') return 'background-color: #dc3545; color: white;';
if (paquete === 'RETORNADO') return 'background-color: #dc3545; color: white;'; if (paquete === 'RETORNADO') return 'background-color: #dc3545; color: white;';
if (paquete === 'COMPLETADO') return 'background-color: #198754; color: white;'; if (paquete === 'COMPLETADO') return 'background-color: #198754; color: white;';
if (paquete === "EMPAQUETADO") return "background-color: #20c997; color: white;"; if (paquete === 'PREPARADO') return 'background-color: #20c997; color: white;';
if (paquete === 'EMPAQUETADO') return 'background-color: #20c997; color: white;';
return 'background-color: #6c757d; color: white;'; return 'background-color: #6c757d; color: white;';
} }
function normalizeTipoPaqueteValueClient(value) {
if (!value) return '';
const cleaned = String(value)
.replace(/[\u00A0\u200B-\u200D\uFEFF]/g, ' ')
.replace(/[\x00-\x1F\x7F]/g, ' ')
.trim()
.replace(/\s+/g, ' ')
.toUpperCase();
const compact = cleaned.replace(/[^A-Z]+/g, '');
const aliases = {
RUTA: 'RUTA',
CONTRAENTREGA: 'CONTRAENTREGA',
NOCONTESTAVOLVERALLAMAR: 'NO CONTESTA, VOLVER A LLAMAR',
PENDIENTEARETORNO: 'PENDIENTE A RETORNO',
COMPLETADO: 'COMPLETADO',
EMPAQUETADO: 'PREPARADO',
PREPARADO: 'PREPARADO',
EMPAQUETARDO: 'PREPARADO',
RETORNADO: 'RETORNADO',
ANULADO: 'ANULADO'
};
return aliases[compact] || cleaned;
}
function getStatusStyleJS(status) { function getStatusStyleJS(status) {
let bgColor = '#0dcaf0'; let bgColor = '#0dcaf0';
let style = 'color: white;'; let style = 'color: white;';
@ -576,15 +607,12 @@ document.addEventListener('DOMContentLoaded', function() {
const select = document.createElement('select'); const select = document.createElement('select');
select.className = 'form-select form-select-sm'; select.className = 'form-select form-select-sm';
const options = [ const options = <?php echo json_encode(array_merge(
{val: '', text: 'Seleccionar'}, [['val' => '', 'text' => 'Seleccionar']],
{val: 'RUTA', text: 'RUTA'}, array_map(static function ($paquete) {
{val: 'ANULADO', text: 'ANULADO'}, return ['val' => $paquete, 'text' => $paquete];
{val: 'PENDIENTE A RETORNO', text: 'PENDIENTE A RETORNO'}, }, tipoPaquetePrimarySelectorValues())
{val: 'RETORNADO', text: 'RETORNADO'}, ), JSON_UNESCAPED_UNICODE); ?>;
{val: "EMPAQUETADO", text: "EMPAQUETADO"},
{val: 'COMPLETADO', text: 'COMPLETADO'}
];
options.forEach(opt => { options.forEach(opt => {
const option = document.createElement('option'); const option = document.createElement('option');
@ -602,7 +630,7 @@ document.addEventListener('DOMContentLoaded', function() {
select.focus(); select.focus();
const save = () => { const save = () => {
const newVal = select.value; const newVal = normalizeTipoPaqueteValueClient(select.value);
// Optimistic update // Optimistic update
cell.dataset.value = newVal; cell.dataset.value = newVal;

View File

@ -11,6 +11,7 @@ if (!isset($_SESSION['user_id'])) {
require_once 'db/config.php'; require_once 'db/config.php';
require_once __DIR__ . '/includes/contraentrega_cobertura.php'; require_once __DIR__ . '/includes/contraentrega_cobertura.php';
require_once __DIR__ . '/includes/tipo_paquete.php';
function redirectPedidoContraentregaWithError(string $message, $id = null, bool $embed = false): void function redirectPedidoContraentregaWithError(string $message, $id = null, bool $embed = false): void
{ {
@ -46,6 +47,7 @@ function normalizeContraentregaCoordinates(string $value): ?string
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pdo = db(); $pdo = db();
ensureTipoPaqueteEnumDefinition($pdo);
$id = $_POST['id'] ?? null; $id = $_POST['id'] ?? null;
$embed_mode = !empty($_POST['embed']) && $_POST['embed'] === '1'; $embed_mode = !empty($_POST['embed']) && $_POST['embed'] === '1';
@ -115,11 +117,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Normalizar Paquete: el selector "Seleccionar" llega como cadena vacía, // Normalizar Paquete: el selector "Seleccionar" llega como cadena vacía,
// pero la columna ENUM permite NULL y no permite ''. // pero la columna ENUM permite NULL y no permite ''.
$tipo_paquete = isset($_POST['tipo_paquete']) ? trim((string)$_POST['tipo_paquete']) : null; $tipo_paquete = normalizeTipoPaqueteValue($_POST['tipo_paquete'] ?? null);
if ($tipo_paquete === '') { $tipos_paquete_validos = tipoPaqueteValidValues();
$tipo_paquete = null;
}
$tipos_paquete_validos = ['RUTA', 'CONTRAENTREGA', 'NO CONTESTA, VOLVER A LLAMAR', 'PENDIENTE A RETORNO', 'COMPLETADO', 'EMPAQUETADO', 'RETORNADO', 'ANULADO'];
if ($tipo_paquete !== null && !in_array($tipo_paquete, $tipos_paquete_validos, true)) { if ($tipo_paquete !== null && !in_array($tipo_paquete, $tipos_paquete_validos, true)) {
redirectPedidoContraentregaWithError('El paquete seleccionado no es válido. Seleccione una opción de la lista.', $id, $embed_mode); redirectPedidoContraentregaWithError('El paquete seleccionado no es válido. Seleccione una opción de la lista.', $id, $embed_mode);
} }

View File

@ -1,17 +1,60 @@
<?php <?php
session_start(); session_start();
require_once 'db/config.php'; require_once 'db/config.php';
require_once __DIR__ . '/includes/tipo_paquete.php';
header('Content-Type: application/json'); header('Content-Type: application/json');
if (!function_exists('normalizeTipoPaqueteValue')) {
function normalizeTipoPaqueteValue($value)
{
if ($value === null || is_array($value)) {
return null;
}
$value = (string) $value;
$value = preg_replace('/[\x{00A0}\x{200B}-\x{200D}\x{FEFF}]+/u', ' ', $value);
$value = preg_replace('/[\x00-\x1F\x7F]+/u', ' ', $value);
$value = preg_replace('/\s+/u', ' ', trim($value));
if ($value === '') {
return null;
}
$normalized = function_exists('mb_strtoupper') ? mb_strtoupper($value, 'UTF-8') : strtoupper($value);
$match = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $normalized);
if ($match === false || $match === null || $match === '') {
$match = $normalized;
}
$canonicalKey = preg_replace('/[^A-Z]+/', '', strtoupper($match));
$aliases = [
'RUTA' => 'RUTA',
'CONTRAENTREGA' => 'CONTRAENTREGA',
'NOCONTESTAVOLVERALLAMAR' => 'NO CONTESTA, VOLVER A LLAMAR',
'PENDIENTEARETORNO' => 'PENDIENTE A RETORNO',
'COMPLETADO' => 'COMPLETADO',
'EMPAQUETADO' => 'PREPARADO',
'PREPARADO' => 'PREPARADO',
'EMPAQUETARDO' => 'PREPARADO',
'RETORNADO' => 'RETORNADO',
'ANULADO' => 'ANULADO',
];
return $aliases[$canonicalKey] ?? $normalized;
}
}
if (!isset($_SESSION['user_id'])) { if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'message' => 'No autorizado']); echo json_encode(['success' => false, 'message' => 'No autorizado']);
exit; exit;
} }
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pedido_id = $_POST['pedido_id'] ?? null; $pedido_id_raw = $_POST['pedido_id'] ?? null;
$tipo_paquete = $_POST['tipo_paquete'] ?? null; $pedido_id = (is_numeric($pedido_id_raw) && (int)$pedido_id_raw > 0) ? (int)$pedido_id_raw : null;
$tipo_paquete = normalizeTipoPaqueteValue($_POST['tipo_paquete'] ?? null);
if (!$pedido_id) { if (!$pedido_id) {
echo json_encode(['success' => false, 'message' => 'ID de pedido faltante']); echo json_encode(['success' => false, 'message' => 'ID de pedido faltante']);
@ -20,18 +63,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try { try {
$pdo = db(); $pdo = db();
ensureTipoPaqueteEnumDefinition($pdo);
if (empty($tipo_paquete)) {
if ($tipo_paquete === null) {
// Allow clearing the selection // Allow clearing the selection
$stmt = $pdo->prepare("UPDATE pedidos SET tipo_paquete = NULL WHERE id = ?"); $stmt = $pdo->prepare("UPDATE pedidos SET tipo_paquete = NULL WHERE id = ?");
$result = $stmt->execute([$pedido_id]); $result = $stmt->execute([$pedido_id]);
} else { } else {
$valid_types = ['RUTA', 'ANULADO', 'PENDIENTE A RETORNO', 'RETORNADO', 'CONTRAENTREGA', 'NO CONTESTA, VOLVER A LLAMAR', 'COMPLETADO', 'EMPAQUETADO']; $valid_types = tipoPaqueteValidValues();
if (!in_array($tipo_paquete, $valid_types)) { if (!in_array($tipo_paquete, $valid_types, true)) {
echo json_encode(['success' => false, 'message' => 'Tipo inválido']); echo json_encode(['success' => false, 'message' => 'Tipo inválido']);
exit; exit;
} }
$stmt = $pdo->prepare("UPDATE pedidos SET tipo_paquete = ? WHERE id = ?"); $stmt = $pdo->prepare("UPDATE pedidos SET tipo_paquete = ? WHERE id = ?");
$result = $stmt->execute([$tipo_paquete, $pedido_id]); $result = $stmt->execute([$tipo_paquete, $pedido_id]);
} }
@ -47,4 +91,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else { } else {
echo json_encode(['success' => false, 'message' => 'Método no permitido']); echo json_encode(['success' => false, 'message' => 'Método no permitido']);
} }
?> ?>