Cambios
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* API: Historial de envíos masivos (broadcasts)
|
||||
* GET ?page=1&per_page=20
|
||||
*/
|
||||
require_once '../config/config.php';
|
||||
requireAuthentication();
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['success' => false, 'error' => 'Método no permitido']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = Database::getInstance();
|
||||
|
||||
// Crear tabla si no existe todavía
|
||||
$db->getConnection()->exec("
|
||||
CREATE TABLE IF NOT EXISTS broadcast_history (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
sent_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
message_type VARCHAR(20) NOT NULL DEFAULT 'text',
|
||||
selection_type VARCHAR(20) NOT NULL DEFAULT 'filter',
|
||||
filter_used VARCHAR(50) NULL,
|
||||
template_name VARCHAR(120) NULL,
|
||||
message_preview TEXT NULL,
|
||||
total_users INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
sent_count INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
error_count INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
sent_by INT UNSIGNED NULL,
|
||||
sent_by_name VARCHAR(120) NULL,
|
||||
INDEX idx_sent_at (sent_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
");
|
||||
|
||||
$page = max(1, (int)($_GET['page'] ?? 1));
|
||||
$perPage = min(100, max(5, (int)($_GET['per_page'] ?? 20)));
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
try {
|
||||
$total = (int)$db->getConnection()
|
||||
->query("SELECT COUNT(*) FROM broadcast_history")
|
||||
->fetchColumn();
|
||||
|
||||
$rows = $db->fetchAll(
|
||||
"SELECT * FROM broadcast_history ORDER BY sent_at DESC LIMIT ? OFFSET ?",
|
||||
[$perPage, $offset]
|
||||
);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'data' => $rows,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'per_page' => $perPage,
|
||||
'pages' => (int)ceil($total / $perPage),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
error_log('get_broadcast_history.php: ' . $e->getMessage());
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'error' => 'Error interno del servidor']);
|
||||
}
|
||||
@@ -9,6 +9,27 @@ require_once '../config/config.php';
|
||||
// Verificar autenticación
|
||||
requireAuthentication();
|
||||
|
||||
// Asegurar que la tabla de historial existe
|
||||
try {
|
||||
Database::getInstance()->getConnection()->exec("
|
||||
CREATE TABLE IF NOT EXISTS broadcast_history (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
sent_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
message_type VARCHAR(20) NOT NULL DEFAULT 'text',
|
||||
selection_type VARCHAR(20) NOT NULL DEFAULT 'filter',
|
||||
filter_used VARCHAR(50) NULL,
|
||||
template_name VARCHAR(120) NULL,
|
||||
message_preview TEXT NULL,
|
||||
total_users INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
sent_count INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
error_count INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
sent_by INT UNSIGNED NULL,
|
||||
sent_by_name VARCHAR(120) NULL,
|
||||
INDEX idx_sent_at (sent_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
");
|
||||
} catch (Exception $_e) { /* silencioso si ya existe */ }
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: POST');
|
||||
@@ -271,6 +292,38 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Guardar historial de broadcast ---
|
||||
try {
|
||||
$adminId = (int)($_SESSION['admin_user']['id'] ?? $_SESSION['user_id'] ?? 0);
|
||||
$adminName = $_SESSION['admin_user']['name'] ?? $_SESSION['username'] ?? 'Sistema';
|
||||
|
||||
$tplName = null;
|
||||
$preview = '';
|
||||
if ($messageType === 'template' && isset($template)) {
|
||||
$tplName = $template['template_name'] ?? $template['name'] ?? null;
|
||||
$preview = mb_substr($template['body'] ?? $tplName ?? '', 0, 200);
|
||||
} else {
|
||||
$preview = mb_substr($input['message'] ?? '', 0, 200);
|
||||
}
|
||||
|
||||
$db->insert('broadcast_history', [
|
||||
'sent_at' => date('Y-m-d H:i:s'),
|
||||
'message_type' => $messageType,
|
||||
'selection_type' => $selectionType,
|
||||
'filter_used' => ($selectionType === 'filter') ? ($input['filter'] ?? 'all') : null,
|
||||
'template_name' => $tplName,
|
||||
'message_preview' => $preview,
|
||||
'total_users' => count($users),
|
||||
'sent_count' => $sentCount,
|
||||
'error_count' => $errorCount,
|
||||
'sent_by' => $adminId ?: null,
|
||||
'sent_by_name' => $adminName ?: null,
|
||||
]);
|
||||
} catch (Exception $eHist) {
|
||||
error_log('broadcast_history insert failed: ' . $eHist->getMessage());
|
||||
}
|
||||
// --- Fin historial ---
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'sent_count' => $sentCount,
|
||||
|
||||
@@ -1947,6 +1947,10 @@ class SimpleWhatsAppManager {
|
||||
$('#broadcast-users').val(null).trigger('change');
|
||||
document.getElementById('broadcast-template-variables').style.display = 'none';
|
||||
document.getElementById('broadcast-template-preview').style.display = 'none';
|
||||
// Refrescar historial automáticamente
|
||||
if (typeof window.loadBroadcastHistory === 'function') {
|
||||
setTimeout(() => window.loadBroadcastHistory(1), 800);
|
||||
}
|
||||
} else {
|
||||
this.showError(result.error || 'Error enviando broadcast');
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ class Domicilio {
|
||||
p.direccion AS paciente_direccion,
|
||||
o.examenes_solicitados,
|
||||
o.indicaciones AS indicaciones_orden,
|
||||
o.local_file AS orden_local_file,
|
||||
e.nombre_completo AS enfermera_nombre,
|
||||
e.telefono AS enfermera_telefono,
|
||||
a.id AS asignacion_id,
|
||||
|
||||
@@ -663,6 +663,44 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historial de Envíos Masivos -->
|
||||
<div class="card mt-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0"><i class="fas fa-history me-2 text-secondary"></i>Historial de Envíos Masivos</h5>
|
||||
<button class="btn btn-sm btn-outline-secondary" onclick="loadBroadcastHistory(1)">
|
||||
<i class="fas fa-sync-alt"></i> Actualizar
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Fecha</th>
|
||||
<th>Tipo</th>
|
||||
<th>Mensaje / Plantilla</th>
|
||||
<th class="text-center">Total</th>
|
||||
<th class="text-center text-success">Enviados</th>
|
||||
<th class="text-center text-danger">Errores</th>
|
||||
<th>Enviado por</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="broadcast-history-tbody">
|
||||
<tr>
|
||||
<td colspan="7" class="text-center text-muted py-4">
|
||||
<i class="fas fa-spinner fa-spin me-1"></i> Cargando historial...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="bh-pagination-row" class="d-flex justify-content-between align-items-center px-3 py-2 border-top" style="display:none!important">
|
||||
<small class="text-muted" id="bh-pagination-info"></small>
|
||||
<div class="d-flex gap-1" id="bh-pagination-btns"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- WhatsApp Profile Tab -->
|
||||
@@ -2191,6 +2229,88 @@ try {
|
||||
})();
|
||||
</script>
|
||||
<!-- ── / T&C Aceptaciones JS ─────────────────────────────────────────── -->
|
||||
|
||||
<!-- ── Historial Envíos Masivos JS ──────────────────────────────────── -->
|
||||
<script>
|
||||
(function () {
|
||||
let _currentPage = 1;
|
||||
|
||||
window.loadBroadcastHistory = function (page) {
|
||||
page = page || 1;
|
||||
_currentPage = page;
|
||||
|
||||
const tbody = document.getElementById('broadcast-history-tbody');
|
||||
if (!tbody) return;
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center text-muted py-3"><i class="fas fa-spinner fa-spin me-1"></i> Cargando...</td></tr>';
|
||||
|
||||
fetch('api/get_broadcast_history.php?page=' + page + '&per_page=10')
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (!res.success || !res.data) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center text-muted py-3">Sin registros</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.data.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center text-muted py-3"><i class="fas fa-inbox me-1"></i> Aún no hay envíos masivos registrados</td></tr>';
|
||||
} else {
|
||||
const typeLabels = { text: 'Texto', template: 'Plantilla', image: 'Imagen', document: 'Documento' };
|
||||
const filterLabels = { all: 'Todos', active: 'Activos', recent: 'Recientes', null: '—' };
|
||||
tbody.innerHTML = res.data.map(r => {
|
||||
const fecha = r.sent_at ? r.sent_at.replace('T', ' ').substring(0, 16) : '—';
|
||||
const tipo = typeLabels[r.message_type] || r.message_type || '—';
|
||||
const msg = r.template_name
|
||||
? '<span class="badge bg-success-subtle text-success border border-success-subtle me-1">Plantilla</span>' + htmlEsc(r.template_name)
|
||||
: (r.message_preview ? htmlEsc(r.message_preview.substring(0, 60)) + (r.message_preview.length > 60 ? '…' : '') : '—');
|
||||
const pct = r.total_users > 0 ? Math.round(r.sent_count / r.total_users * 100) : 0;
|
||||
return `<tr>
|
||||
<td class="small text-nowrap">${fecha}</td>
|
||||
<td><span class="badge bg-secondary-subtle text-secondary border">${tipo}</span></td>
|
||||
<td class="small">${msg}</td>
|
||||
<td class="text-center fw-bold">${r.total_users}</td>
|
||||
<td class="text-center text-success fw-bold">${r.sent_count} <small class="text-muted">(${pct}%)</small></td>
|
||||
<td class="text-center ${r.error_count > 0 ? 'text-danger fw-bold' : 'text-muted'}">${r.error_count}</td>
|
||||
<td class="small text-muted">${htmlEsc(r.sent_by_name || 'Sistema')}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// Paginación
|
||||
const pagRow = document.getElementById('bh-pagination-row');
|
||||
const pagInfo = document.getElementById('bh-pagination-info');
|
||||
const pagBtns = document.getElementById('bh-pagination-btns');
|
||||
if (pagRow && res.pages > 1) {
|
||||
pagRow.style.display = '';
|
||||
pagInfo.textContent = 'Página ' + res.page + ' de ' + res.pages + ' (' + res.total + ' registros)';
|
||||
let btns = '';
|
||||
for (let p = 1; p <= res.pages; p++) {
|
||||
btns += `<button class="btn btn-sm ${p === res.page ? 'btn-secondary' : 'btn-outline-secondary'}" onclick="loadBroadcastHistory(${p})">${p}</button>`;
|
||||
}
|
||||
pagBtns.innerHTML = btns;
|
||||
} else if (pagRow) {
|
||||
pagRow.style.display = 'none';
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (tbody) tbody.innerHTML = '<tr><td colspan="7" class="text-center text-danger py-3">Error al cargar el historial</td></tr>';
|
||||
console.error('loadBroadcastHistory error:', err);
|
||||
});
|
||||
};
|
||||
|
||||
function htmlEsc(str) {
|
||||
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
||||
}
|
||||
|
||||
// Cargar al activar el tab de broadcast
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const broadcastLinks = document.querySelectorAll('.nav-link[data-tab="broadcast"], [data-tab="broadcast"]');
|
||||
broadcastLinks.forEach(link => {
|
||||
link.addEventListener('click', () => setTimeout(() => loadBroadcastHistory(1), 100));
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<!-- ── / Historial Envíos Masivos JS ─────────────────────────────────── -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+173
-5
@@ -148,7 +148,7 @@ $domIdParam = (int)($_GET['id'] ?? 0);
|
||||
<div class="modal-body">
|
||||
<form id="form-domicilio">
|
||||
<input type="hidden" name="id" id="dom-id">
|
||||
<input type="hidden" name="orden_id" id="dom-orden-id" value="<?= $ordenIdParam ?>">
|
||||
<input type="hidden" name="orden_id_url" id="dom-orden-id" value="<?= $ordenIdParam ?>">
|
||||
|
||||
<!-- ── Paciente ── -->
|
||||
<h6 class="text-muted text-uppercase small fw-semibold border-bottom pb-1 mb-3">
|
||||
@@ -251,6 +251,44 @@ $domIdParam = (int)($_GET['id'] ?? 0);
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Orden Médica ── -->
|
||||
<h6 class="text-muted text-uppercase small fw-semibold border-bottom pb-1 mb-3">
|
||||
<i class="fas fa-file-medical me-1"></i> Orden Médica Adjunta
|
||||
</h6>
|
||||
<div class="mb-3">
|
||||
<input type="hidden" name="orden_id" id="dom-orden-id-form">
|
||||
<!-- Preview archivo actual o pendiente -->
|
||||
<div id="dom-orden-preview" class="d-flex align-items-center gap-3 p-2 rounded border bg-light mb-2 d-none">
|
||||
<div id="dom-orden-thumb-wrap">
|
||||
<img id="dom-orden-img" src="" alt="Orden" style="max-height:80px;max-width:100px;object-fit:contain;border-radius:4px;display:none">
|
||||
<div id="dom-orden-icon" class="d-none">
|
||||
<i class="fas fa-file-alt fa-3x text-secondary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1 overflow-hidden">
|
||||
<div id="dom-orden-fname" class="small fw-semibold text-truncate"></div>
|
||||
<div id="dom-orden-fsize" class="small text-muted"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dom-orden-empty" class="small text-muted mb-2">
|
||||
<i class="fas fa-paperclip me-1"></i> Sin orden adjunta
|
||||
</div>
|
||||
<div class="d-flex gap-2 flex-wrap align-items-center">
|
||||
<label class="btn btn-sm btn-outline-primary mb-0" for="dom-orden-input">
|
||||
<i class="fas fa-upload me-1"></i>
|
||||
<span id="dom-orden-btn-lbl">Adjuntar orden</span>
|
||||
</label>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger d-none" id="dom-orden-quitar"
|
||||
onclick="domQuitarOrden()">
|
||||
<i class="fas fa-times me-1"></i> Quitar
|
||||
</button>
|
||||
</div>
|
||||
<input type="file" id="dom-orden-input" class="d-none"
|
||||
accept="image/jpeg,image/png,image/gif,image/webp,application/pdf,.pdf,.doc,.docx"
|
||||
onchange="domSeleccionarOrdenFile(this)">
|
||||
<small class="text-muted d-block mt-1">Imagen, PDF o DOC — máx. 10 MB</small>
|
||||
</div>
|
||||
|
||||
<!-- ── Notas ── -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Notas internas</label>
|
||||
@@ -270,6 +308,93 @@ $domIdParam = (int)($_GET['id'] ?? 0);
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
const modal = new bootstrap.Modal('#modalDomicilio');
|
||||
|
||||
// ── Estado orden en el modal ───────────────────────────────────────────────
|
||||
let _domOrderFile = null; // File pendiente de subir
|
||||
let _domCurrentLocalFile = null; // local_file actual de la orden
|
||||
let _domRemoveOrder = false; // el usuario quiere desvincularse de la orden
|
||||
|
||||
function _domResetOrden() {
|
||||
_domOrderFile = null;
|
||||
_domCurrentLocalFile = null;
|
||||
_domRemoveOrder = false;
|
||||
document.getElementById('dom-orden-id-form').value = '';
|
||||
document.getElementById('dom-orden-input').value = '';
|
||||
_domRenderOrdenPreview();
|
||||
}
|
||||
|
||||
function _domRenderOrdenPreview() {
|
||||
const preview = document.getElementById('dom-orden-preview');
|
||||
const empty = document.getElementById('dom-orden-empty');
|
||||
const img = document.getElementById('dom-orden-img');
|
||||
const icon = document.getElementById('dom-orden-icon');
|
||||
const fname = document.getElementById('dom-orden-fname');
|
||||
const fsize = document.getElementById('dom-orden-fsize');
|
||||
const btnQuitar = document.getElementById('dom-orden-quitar');
|
||||
const btnLbl = document.getElementById('dom-orden-btn-lbl');
|
||||
|
||||
if (_domOrderFile) {
|
||||
// Archivo local seleccionado aún no subido
|
||||
const isImg = _domOrderFile.type.startsWith('image/');
|
||||
if (isImg) {
|
||||
img.src = URL.createObjectURL(_domOrderFile);
|
||||
img.style.display = '';
|
||||
icon.classList.add('d-none');
|
||||
} else {
|
||||
img.style.display = 'none';
|
||||
icon.classList.remove('d-none');
|
||||
}
|
||||
fname.textContent = _domOrderFile.name;
|
||||
fsize.textContent = (_domOrderFile.size / 1024).toFixed(1) + ' KB — pendiente de guardar';
|
||||
preview.classList.remove('d-none');
|
||||
empty.classList.add('d-none');
|
||||
btnQuitar.classList.remove('d-none');
|
||||
btnLbl.textContent = 'Cambiar archivo';
|
||||
} else if (_domCurrentLocalFile && !_domRemoveOrder) {
|
||||
// Archivo ya guardado en servidor
|
||||
const isImg = /\.(jpe?g|png|gif|webp)$/i.test(_domCurrentLocalFile);
|
||||
if (isImg) {
|
||||
img.src = 'uploads/media/' + encodeURIComponent(_domCurrentLocalFile);
|
||||
img.style.display = '';
|
||||
icon.classList.add('d-none');
|
||||
} else {
|
||||
img.style.display = 'none';
|
||||
icon.classList.remove('d-none');
|
||||
}
|
||||
fname.textContent = _domCurrentLocalFile;
|
||||
fsize.textContent = 'Archivo guardado';
|
||||
preview.classList.remove('d-none');
|
||||
empty.classList.add('d-none');
|
||||
btnQuitar.classList.remove('d-none');
|
||||
btnLbl.textContent = 'Cambiar archivo';
|
||||
} else {
|
||||
preview.classList.add('d-none');
|
||||
empty.classList.remove('d-none');
|
||||
btnQuitar.classList.add('d-none');
|
||||
btnLbl.textContent = 'Adjuntar orden';
|
||||
}
|
||||
}
|
||||
|
||||
function domSeleccionarOrdenFile(input) {
|
||||
const file = input.files[0];
|
||||
if (!file) return;
|
||||
if (file.size > 10 * 1024 * 1024) {
|
||||
alert('El archivo supera los 10 MB permitidos');
|
||||
input.value = '';
|
||||
return;
|
||||
}
|
||||
_domOrderFile = file;
|
||||
_domRemoveOrder = false;
|
||||
_domRenderOrdenPreview();
|
||||
}
|
||||
|
||||
function domQuitarOrden() {
|
||||
_domOrderFile = null;
|
||||
_domRemoveOrder = true;
|
||||
document.getElementById('dom-orden-id-form').value = '';
|
||||
document.getElementById('dom-orden-input').value = '';
|
||||
_domRenderOrdenPreview();
|
||||
}
|
||||
const COLOR_DOM = { programado:'secondary', confirmado:'info', en_camino:'primary', en_domicilio:'warning', completado:'success', cancelado:'danger', reprogramado:'dark' };
|
||||
let domSeleccionado = <?= $domIdParam ?: 'null' ?>;
|
||||
let paginaActual = 1;
|
||||
@@ -547,6 +672,7 @@ function abrirFormulario() {
|
||||
document.getElementById('dom-fecha').value = document.getElementById('filtro-fecha').value || '<?= date('Y-m-d') ?>';
|
||||
document.getElementById('dom-tipo-cliente').value = 'particular';
|
||||
toggleSeguro('particular');
|
||||
_domResetOrden();
|
||||
document.getElementById('modal-titulo').textContent = 'Nuevo Domicilio';
|
||||
modal.show();
|
||||
|
||||
@@ -585,6 +711,13 @@ async function editarDomicilio(id) {
|
||||
document.getElementById('dom-valor-cop').value = dom.valor_copago || '';
|
||||
document.getElementById('dom-copago-lab').value = dom.copago_laboratorio || '';
|
||||
document.getElementById('dom-notas').value = dom.notas_admin || '';
|
||||
|
||||
// Orden médica adjunta
|
||||
_domResetOrden();
|
||||
document.getElementById('dom-orden-id-form').value = dom.orden_id || '';
|
||||
_domCurrentLocalFile = dom.orden_local_file || null;
|
||||
_domRenderOrdenPreview();
|
||||
|
||||
modal.show();
|
||||
}
|
||||
|
||||
@@ -596,11 +729,45 @@ function toggleSeguro(val) {
|
||||
async function guardarDomicilio() {
|
||||
const form = document.getElementById('form-domicilio');
|
||||
if (!form.checkValidity()) { form.reportValidity(); return; }
|
||||
if (!document.getElementById('dom-paciente-id').value) {
|
||||
alert('Debes seleccionar un paciente'); return;
|
||||
}
|
||||
const pacienteId = document.getElementById('dom-paciente-id').value;
|
||||
if (!pacienteId) { alert('Debes seleccionar un paciente'); return; }
|
||||
|
||||
const datos = Object.fromEntries(new FormData(form).entries());
|
||||
if (!datos.id) delete datos.id;
|
||||
// Tomar orden_id del campo oculto real (no el parámetro URL)
|
||||
datos.orden_id = document.getElementById('dom-orden-id-form').value || null;
|
||||
delete datos.orden_id_url;
|
||||
|
||||
// ── Gestión del archivo de orden médica ──────────────────────────────
|
||||
if (_domRemoveOrder) {
|
||||
datos.orden_id = null;
|
||||
} else if (_domOrderFile) {
|
||||
// Subir el archivo primero
|
||||
const fd = new FormData();
|
||||
fd.append('file', _domOrderFile);
|
||||
const upR = await fetch('api/lab/upload_orden.php', { method:'POST', body: fd });
|
||||
const upD = await upR.json();
|
||||
if (!upD.success) {
|
||||
mostrarToast('Error subiendo el archivo: ' + (upD.error || 'desconocido'), 'danger');
|
||||
return;
|
||||
}
|
||||
// Actualizar o crear la orden médica
|
||||
const orId = document.getElementById('dom-orden-id-form').value;
|
||||
const orPayload = orId
|
||||
? { id: parseInt(orId), local_file: upD.local_file }
|
||||
: { paciente_id: parseInt(pacienteId), local_file: upD.local_file };
|
||||
const orR = await fetch('api/lab/save_orden.php', {
|
||||
method:'POST', headers:{'Content-Type':'application/json'},
|
||||
body: JSON.stringify(orPayload),
|
||||
});
|
||||
const orD = await orR.json();
|
||||
if (!orD.success) {
|
||||
mostrarToast('Error guardando la orden: ' + (orD.error || 'desconocido'), 'danger');
|
||||
return;
|
||||
}
|
||||
datos.orden_id = orD.id ?? orD.data?.id ?? (parseInt(orId) || null);
|
||||
}
|
||||
// ── Guardar domicilio ────────────────────────────────────────────────
|
||||
if (!datos.orden_id) delete datos.orden_id;
|
||||
|
||||
const r = await fetch('api/lab/save_domicilio.php', {
|
||||
@@ -611,7 +778,8 @@ async function guardarDomicilio() {
|
||||
if (d.success) {
|
||||
modal.hide();
|
||||
mostrarToast(d.message, 'success');
|
||||
const editadoId = datos.id ? parseInt(datos.id) : null;
|
||||
const editadoId = datos.id ? parseInt(datos.id) : (d.id || null);
|
||||
_domResetOrden();
|
||||
await cargarLista(paginaActual);
|
||||
if (editadoId) verDomicilio(editadoId);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user