refactor(hours): FK user_id en tramites_hours y tramites_obs
Hasta ahora el vínculo "esta hora/observación es de X" era por string (h.abogado = users.name). Se rompía cuando un Socio renombraba un usuario en el Panel de Control (las entradas históricas conservaban el nombre viejo y los filtros del Reporte de Horas no las hallaban). - Migración 014: ADD COLUMN user_id INT NULL + FK ON DELETE SET NULL en ambas tablas, con backfill via JOIN users.name = abogado - tramites/api.php: helper userIdByName() + add_obs/add_hours/ update_hours ahora persisten user_id junto con el string abogado - horas/api.php: filtro WHERE (user_id = :uid OR (user_id IS NULL AND abogado = :name)) — prioriza FK, cae al string solo para filas legacy sin user_id. by_user y by_user_tramite agrupan por COALESCE(u.name, h.abogado) para usar siempre el nombre actual.
This commit is contained in:
+37
-21
@@ -26,23 +26,26 @@ try {
|
||||
$to = clean_date($_GET['to'] ?? null);
|
||||
$userParam = isset($_GET['user']) ? (int)$_GET['user'] : 0;
|
||||
|
||||
// Determinar por qué nombre filtrar:
|
||||
// - Socio/admin: por user seleccionado, o todos si user=0
|
||||
// - Resto: forzado a sus propias horas (matched por su name)
|
||||
$filterName = null;
|
||||
// Determinar por qué usuario filtrar:
|
||||
// - Socio/admin: por user seleccionado (id+nombre), o todos si user=0
|
||||
// - Resto: forzado a su propio user_id (con fallback a su name para legacy)
|
||||
$filterUserId = null;
|
||||
$filterName = null;
|
||||
if (Auth::isSocio()) {
|
||||
if ($userParam > 0) {
|
||||
$sel = $pdo->prepare('SELECT name FROM users WHERE id = :id');
|
||||
$sel = $pdo->prepare('SELECT id, name FROM users WHERE id = :id');
|
||||
$sel->execute([':id' => $userParam]);
|
||||
$name = $sel->fetchColumn();
|
||||
if ($name !== false && $name !== '') $filterName = (string)$name;
|
||||
$u = $sel->fetch();
|
||||
if ($u) { $filterUserId = (int)$u['id']; $filterName = (string)$u['name']; }
|
||||
}
|
||||
} else {
|
||||
$filterName = Auth::userName();
|
||||
if ($filterName === '') {
|
||||
$filterUserId = Auth::userId();
|
||||
$filterName = Auth::userName();
|
||||
if ($filterUserId <= 0 && $filterName === '') {
|
||||
ok([
|
||||
'entries' => [],
|
||||
'by_user' => [],
|
||||
'by_user_tramite' => [],
|
||||
'avail_users' => [],
|
||||
'total_hrs' => 0,
|
||||
'is_socio' => false,
|
||||
@@ -52,9 +55,16 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
// Filtro por usuario: prefiere user_id (canónico); cae al name solo
|
||||
// para filas legacy donde user_id quedó NULL.
|
||||
$where = ['1=1'];
|
||||
$params = [];
|
||||
if ($filterName !== null) {
|
||||
if ($filterUserId !== null && $filterUserId > 0) {
|
||||
$where[] = '(h.user_id = :uid OR (h.user_id IS NULL AND h.abogado = :name))';
|
||||
$params[':uid'] = $filterUserId;
|
||||
$params[':name'] = (string)$filterName;
|
||||
} elseif ($filterName !== null && $filterName !== '') {
|
||||
// Fallback: solo nombre disponible (no debería ocurrir tras 014)
|
||||
$where[] = 'h.abogado = :name';
|
||||
$params[':name'] = $filterName;
|
||||
}
|
||||
@@ -102,10 +112,12 @@ try {
|
||||
if ($to) { $byWhere[] = 'h.fecha <= :to'; $byParams[':to'] = $to . ' 23:59:59'; }
|
||||
$whereByUser = implode(' AND ', $byWhere);
|
||||
|
||||
$bySql = "SELECT h.abogado AS name, SUM(h.hrs) AS total, COUNT(*) AS entries
|
||||
$bySql = "SELECT COALESCE(u.name, h.abogado) AS name,
|
||||
SUM(h.hrs) AS total, COUNT(*) AS entries
|
||||
FROM tramites_hours h
|
||||
LEFT JOIN users u ON u.id = h.user_id
|
||||
WHERE $whereByUser
|
||||
GROUP BY h.abogado
|
||||
GROUP BY COALESCE(u.name, h.abogado)
|
||||
ORDER BY total DESC";
|
||||
$byStmt = $pdo->prepare($bySql);
|
||||
$byStmt->execute($byParams);
|
||||
@@ -117,16 +129,18 @@ try {
|
||||
unset($bu);
|
||||
|
||||
// Breakdown por usuario × trámite
|
||||
$butSql = "SELECT h.abogado AS name, t.id AS tramite_id, t.codigo AS tramite_codigo,
|
||||
$butSql = "SELECT COALESCE(u.name, h.abogado) AS name,
|
||||
t.id AS tramite_id, t.codigo AS tramite_codigo,
|
||||
t.departamento AS departamento,
|
||||
COALESCE(NULLIF(t.nombre,''), NULLIF(t.tipo_tramite,''), NULLIF(t.tipo_proceso,''), t.codigo) AS tramite_title,
|
||||
t.cliente AS tramite_cliente,
|
||||
SUM(h.hrs) AS total, COUNT(*) AS entries
|
||||
FROM tramites_hours h
|
||||
JOIN tramites_legales t ON t.id = h.tramite_id
|
||||
LEFT JOIN users u ON u.id = h.user_id
|
||||
WHERE $whereByUser
|
||||
GROUP BY h.abogado, t.id
|
||||
ORDER BY h.abogado ASC, total DESC";
|
||||
GROUP BY COALESCE(u.name, h.abogado), t.id
|
||||
ORDER BY name ASC, total DESC";
|
||||
$butStmt = $pdo->prepare($butSql);
|
||||
$butStmt->execute($byParams);
|
||||
$byUserTramite = $butStmt->fetchAll();
|
||||
@@ -136,21 +150,23 @@ try {
|
||||
$r['entries'] = (int)$r['entries'];
|
||||
}
|
||||
unset($r);
|
||||
} elseif ($filterName !== null) {
|
||||
// Abogado/usuario regular: su propio desglose por trámite
|
||||
$butParams = [':name' => $filterName];
|
||||
$butWhere = ['h.abogado = :name'];
|
||||
} elseif ($filterUserId !== null && $filterUserId > 0) {
|
||||
// Abogado/usuario regular: su propio desglose por trámite (vía user_id + fallback name)
|
||||
$butParams = [':uid' => $filterUserId, ':name' => (string)$filterName];
|
||||
$butWhere = ['(h.user_id = :uid OR (h.user_id IS NULL AND h.abogado = :name))'];
|
||||
if ($from) { $butWhere[] = 'h.fecha >= :from'; $butParams[':from'] = $from . ' 00:00:00'; }
|
||||
if ($to) { $butWhere[] = 'h.fecha <= :to'; $butParams[':to'] = $to . ' 23:59:59'; }
|
||||
$butSql = "SELECT h.abogado AS name, t.id AS tramite_id, t.codigo AS tramite_codigo,
|
||||
$butSql = "SELECT COALESCE(u.name, h.abogado) AS name,
|
||||
t.id AS tramite_id, t.codigo AS tramite_codigo,
|
||||
t.departamento AS departamento,
|
||||
COALESCE(NULLIF(t.nombre,''), NULLIF(t.tipo_tramite,''), NULLIF(t.tipo_proceso,''), t.codigo) AS tramite_title,
|
||||
t.cliente AS tramite_cliente,
|
||||
SUM(h.hrs) AS total, COUNT(*) AS entries
|
||||
FROM tramites_hours h
|
||||
JOIN tramites_legales t ON t.id = h.tramite_id
|
||||
LEFT JOIN users u ON u.id = h.user_id
|
||||
WHERE " . implode(' AND ', $butWhere) . "
|
||||
GROUP BY h.abogado, t.id
|
||||
GROUP BY COALESCE(u.name, h.abogado), t.id
|
||||
ORDER BY total DESC";
|
||||
$butStmt = $pdo->prepare($butSql);
|
||||
$butStmt->execute($butParams);
|
||||
|
||||
Reference in New Issue
Block a user