action_checador.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
  3. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  4. header('Cache-Control: no-store, no-cache, must-revalidate');
  5. header('Cache-Control: post-check=0, pre-check=0', false);
  6. header('Pragma: no-cache');
  7. header("Content-Type: application/json; charset=utf-8");
  8. header("Access-Control-Allow-Origin: *");
  9. date_default_timezone_set('America/Mexico_City');
  10. #die("error");
  11. ini_set('display_errors', 1);
  12. ini_set('display_startup_errors', 1);
  13. error_reporting(E_ALL);
  14. ignore_user_abort(true);
  15. set_time_limit(0);
  16. function error_response($failure, array $info = [], array $errores = [])
  17. {
  18. $mensajes = [
  19. "clave" => "Faltó la clave del profesor",
  20. "profesor" => "No se encontró el profesor",
  21. "horario" => "No se encontró el horario",
  22. "asistencia" => "No se pudo registrar la asistencia",
  23. "hora" => "No se pudo obtener la hora",
  24. ];
  25. die(json_encode(array_merge([
  26. 'ok' => false,
  27. 'msg' => $mensajes[$failure],
  28. 'failure' => $failure,
  29. 'errores' => $errores,
  30. 'horarios' => [],
  31. 'duplicadas' => [],
  32. // 'env' => $_ENV,
  33. ], $info), JSON_PRETTY_PRINT));
  34. }
  35. require_once "include/bd_pdo.php";
  36. require_once "include/LogAsistencias.php";
  37. $log = new LogAsistencias();
  38. $clave = $_POST['cve'] ?? $_GET['cve'] ?? null;
  39. $log_id = $db->insert('log_registro', [
  40. 'clave' => $clave,
  41. 'ip' => $_SERVER['REMOTE_ADDR'],
  42. 'navegador' => $_SERVER['HTTP_USER_AGENT'] ?? 'Móvil',
  43. 'informacion' => 'Conexión',
  44. 'detalle' => 'Se hizo una conexión al servidor',
  45. ], 'log_id');
  46. if (is_null($clave))
  47. error_response("datos");
  48. // Datos de usuario
  49. $profesor = $db->querySingle(
  50. "SELECT * FROM profesor WHERE profesor_clave::INT = :clave",
  51. [':clave' => intval(preg_replace('/[^0-9]/', '', $clave))]
  52. );
  53. if (empty($profesor)) {
  54. $log->appendLog($clave, "ND", "No registrada [Error] Msg: No se encontró el profesor");
  55. $db->where('log_id', $log_id)->update(
  56. 'log_registro',
  57. [
  58. 'informacion' => 'Profesor',
  59. 'detalle' => 'No registrada [Error] Msg: No se encontró el profesor',
  60. ]
  61. );
  62. error_response("profesor", array("clave" => $clave));
  63. } else {
  64. $db->where('log_id', $log_id)->update(
  65. 'log_registro',
  66. [
  67. 'profesor' => $profesor['profesor_nombre'],
  68. ]
  69. );
  70. // profesor -> profesor_horario -> horario -> materia -> carrera
  71. // get carreras from a profesor:
  72. $carreras = array_map(
  73. fn($carrera) => $carrera['carrera_id'],
  74. $db->query(
  75. "SELECT DISTINCT carrera_id FROM horario_profesor
  76. join horario using (horario_id)
  77. join materia using (materia_id)
  78. join carrera using (carrera_id)
  79. where profesor_id = :profesor_id",
  80. [':profesor_id' => $profesor['profesor_id']]
  81. )
  82. );
  83. }
  84. $avisos = array_map(fn($aviso) => $aviso['aviso_texto'], $db
  85. ->join('aviso_profesor', 'aviso.aviso_id = aviso_profesor.aviso_id', 'LEFT')
  86. ->join('aviso_carrera', 'aviso.aviso_id = aviso_carrera.aviso_id', 'LEFT')
  87. ->where('carrera_id', $carreras)
  88. ->where('profesor_id', $profesor['profesor_id'], '=', 'OR')
  89. ->where('aviso_fecha_inicial', date('Y-m-d'), '<=')
  90. ->where('aviso_fecha_final', date('Y-m-d'), '>=')
  91. ->where('aviso_estado')
  92. ->get("aviso"));
  93. $asistencia = $db->query(
  94. isset($_POST['cve']) ?
  95. "WITH horarios AS (
  96. SELECT horario_view.*, profesor_id, CURRENT_TIME > (HORARIO_HORA + :retardo * INTERVAL '1 minute') as retardo FROM horario_view
  97. join horario_profesor using (horario_id)
  98. where CURRENT_TIME between horario_hora - interval '1 MINUTE' * :antes and horario_hora + interval '1 MINUTE' * :despues
  99. and (HORARIO_DIA, PROFESOR_ID) = (EXTRACT('DOW' FROM CURRENT_DATE), :profesor_id)
  100. ),
  101. reposiciones AS (
  102. SELECT horario_view.*, profesor_id, CURRENT_TIME > (HORARIO_HORA + :retardo * INTERVAL '1 minute') as retardo FROM horario_view
  103. join registro using (horario_id)
  104. join reposicion using (reposicion_id)
  105. where CURRENT_TIME between REPOSICION_HORA - interval '1 MINUTE' * :antes and REPOSICION_HORA + interval '1 MINUTE' * :despues
  106. and (REPOSICION_FECHA, PROFESOR_ID) = (CURRENT_DATE, :profesor_id)
  107. ),
  108. registros AS (
  109. INSERT INTO public.registro(registro_fecha, registro_retardo, horario_id, registro_fecha_ideal, profesor_id)
  110. select NOW(), retardo, horario_id, current_date, profesor_id from horarios
  111. UNION
  112. SELECT NOW(), retardo, horario_id, current_date, profesor_id from reposiciones
  113. ON CONFLICT (horario_id, registro_fecha_ideal, profesor_id) DO UPDATE SET registro_fecha = COALESCE(registro.registro_fecha, NOW())
  114. RETURNING *, (NOW() <> registro_fecha) duplicado
  115. )
  116. SELECT HORARIOS.*, REGISTROS.*
  117. FROM horarios
  118. LEFT JOIN registros using (horario_id, profesor_id)
  119. UNION
  120. SELECT REPOSICIONES.*, REGISTROS.*
  121. FROM reposiciones
  122. LEFT JOIN registros using (horario_id, profesor_id)
  123. "
  124. : (isset($_GET['cve']) ?
  125. "SELECT *, registro_fecha is not null duplicado, :retardo FROM horario_view
  126. join horario_profesor using (horario_id)
  127. left join registro on (horario_view.horario_id, horario_profesor.profesor_id, current_date) = (registro.horario_id, registro.profesor_id, registro.registro_fecha_ideal)
  128. where current_time between horario_hora - interval '1 MINUTE' * :antes and horario_hora + interval '1 MINUTE' * :despues
  129. and (HORARIO_DIA, horario_profesor.PROFESOR_ID) = (EXTRACT('DOW' FROM CURRENT_DATE), :profesor_id)"
  130. : "SELECT NULL"),
  131. [
  132. ':antes' => $_ENV['ANTES'],
  133. ':despues' => $_ENV['DESPUES'],
  134. ':retardo' => $_ENV['RETARDO'],
  135. ':profesor_id' => $profesor['profesor_id'],
  136. ]
  137. );
  138. if (empty($asistencia)) {
  139. $log->appendLog($profesor['profesor_clave'], $profesor['profesor_nombre'], "No registrada [Error] Msg: No se encontró el horario");
  140. $db->where('log_id', $log_id)->update(
  141. 'log_registro',
  142. [
  143. 'informacion' => 'Horario',
  144. 'detalle' => 'No registrada [Error] Msg: No se encontró el horario',
  145. ]
  146. );
  147. // if method post
  148. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  149. $curl = curl_init();
  150. curl_setopt_array($curl, [
  151. CURLOPT_URL => "{$_ENV['PAAD_URL']}/api/horario_profesor_log.php",
  152. CURLOPT_TIMEOUT => 1,
  153. CURLOPT_CUSTOMREQUEST => "POST",
  154. CURLOPT_POSTFIELDS => json_encode([
  155. 'profesor_id' => $profesor['profesor_id'],
  156. 'log_id' => $log_id,
  157. ])
  158. ]);
  159. curl_exec($curl);
  160. curl_close($curl);
  161. }
  162. error_response(
  163. "horario",
  164. info: [
  165. 'nombre' => $profesor['profesor_nombre'],
  166. 'avisos' => $avisos,
  167. ]
  168. );
  169. }
  170. $duplicadas = array_filter($asistencia, fn($registro) => $registro['duplicado']);
  171. $horarios = array_filter($asistencia, fn($registro) => !$registro['duplicado']);
  172. if (!empty($duplicadas)) {
  173. $log->appendLog($profesor['profesor_clave'], $profesor['profesor_nombre'], "No registrada [Duplicada] Msg: Ya se registró la asistencia");
  174. $db->where('log_id', $log_id)->update(
  175. 'log_registro',
  176. [
  177. 'informacion' => 'Asistencia',
  178. 'detalle' => 'No registrada [Duplicada] Msg: Ya se registró la asistencia',
  179. 'success' => true,
  180. 'horarios' => json_encode($asistencia),
  181. ]
  182. );
  183. } else {
  184. $log->appendLog($profesor['profesor_clave'], $profesor['profesor_nombre'], "Registrada");
  185. $db->where('log_id', $log_id)->update(
  186. 'log_registro',
  187. [
  188. 'informacion' => 'Asistencia',
  189. 'detalle' => 'Registrada',
  190. 'success' => true,
  191. 'horarios' => json_encode($asistencia),
  192. ]
  193. );
  194. }
  195. $duplicadas = array_reduce($duplicadas, function ($carry, $horario) use ($db) {
  196. // $facultad = $horario['facultad_id'];
  197. $facultad = $db->where('facultad_id', $horario['facultad_id'])->getOne('facultad')['facultad_nombre'];
  198. if (!isset($carry[$facultad]))
  199. $carry[$facultad] = [];
  200. $carry[$facultad][] = $horario;
  201. return $carry;
  202. }, []);
  203. // collect in one array all the horarios by facultad_nombre => {$horarios}
  204. $horarios = array_reduce($horarios, function ($carry, $horario) use ($db) {
  205. // $facultad = $horario['facultad_id'];
  206. $facultad = $db->where('facultad_id', $horario['facultad_id'])->getOne('facultad')['facultad_nombre'];
  207. if (!isset($carry[$facultad]))
  208. $carry[$facultad] = [];
  209. $carry[$facultad][] = $horario;
  210. return $carry;
  211. }, []);
  212. die(json_encode([
  213. 'ok' => true,
  214. 'profesor' => $profesor,
  215. 'horarios' => $horarios,
  216. 'duplicadas' => $duplicadas,
  217. 'avisos' => $avisos,
  218. ], JSON_PRETTY_PRINT));