Commit Bulk
This commit is contained in:
@@ -24,8 +24,16 @@ try {
|
|||||||
fechas AS (
|
fechas AS (
|
||||||
SELECT fechas_clase(h.horario_id) as registro_fecha_ideal, h.horario_id
|
SELECT fechas_clase(h.horario_id) as registro_fecha_ideal, h.horario_id
|
||||||
FROM horarios h
|
FROM horarios h
|
||||||
|
),
|
||||||
|
sin_registro AS (
|
||||||
|
SELECT * FROM ESTADO_SUPERVISOR WHERE (estado_color, estado_icon) = ('dark', 'ing-cancelar')
|
||||||
)
|
)
|
||||||
SELECT estado_supervisor.*, usuario.*, registro.*, profesor.*, horarios.*, fechas.*,
|
SELECT
|
||||||
|
usuario.*, registro.*, profesor.*, horarios.*, fechas.*,
|
||||||
|
coalesce(estado_supervisor.estado_supervisor_id, sin_registro.estado_supervisor_id) as estado_supervisor_id,
|
||||||
|
coalesce(estado_supervisor.nombre, sin_registro.nombre) as nombre,
|
||||||
|
coalesce(estado_supervisor.estado_color, sin_registro.estado_color) as estado_color,
|
||||||
|
coalesce(estado_supervisor.estado_icon, sin_registro.estado_icon) as estado_icon,
|
||||||
justificador.usuario_nombre as justificador_nombre,
|
justificador.usuario_nombre as justificador_nombre,
|
||||||
justificador.usuario_clave as justificador_clave,
|
justificador.usuario_clave as justificador_clave,
|
||||||
facultad.facultad_nombre as justificador_facultad,
|
facultad.facultad_nombre as justificador_facultad,
|
||||||
@@ -36,6 +44,7 @@ try {
|
|||||||
JOIN profesor using (profesor_id)
|
JOIN profesor using (profesor_id)
|
||||||
LEFT JOIN registro USING (horario_id, registro_fecha_ideal, profesor_id)
|
LEFT JOIN registro USING (horario_id, registro_fecha_ideal, profesor_id)
|
||||||
LEFT join estado_supervisor using (estado_supervisor_id)
|
LEFT join estado_supervisor using (estado_supervisor_id)
|
||||||
|
CROSS JOIN sin_registro
|
||||||
LEFT JOIN USUARIO ON USUARIO.usuario_id = REGISTRO.supervisor_id
|
LEFT JOIN USUARIO ON USUARIO.usuario_id = REGISTRO.supervisor_id
|
||||||
LEFT JOIN USUARIO JUSTIFICADOR ON JUSTIFICADOR.usuario_id = REGISTRO.justificador_id
|
LEFT JOIN USUARIO JUSTIFICADOR ON JUSTIFICADOR.usuario_id = REGISTRO.justificador_id
|
||||||
LEFT JOIN ROL on ROL.rol_id = justificador.rol_id
|
LEFT JOIN ROL on ROL.rol_id = justificador.rol_id
|
||||||
|
|||||||
@@ -1,35 +1,56 @@
|
|||||||
<?php
|
<?
|
||||||
header('Content-Type: application/json');
|
#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 = "../";
|
$ruta = "../";
|
||||||
require_once("../include/bd_pdo.php");
|
require_once $ruta . "class/c_login.php";
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
extract($_POST);
|
http_response_code(401);
|
||||||
|
die(json_encode(['error' => 'unauthorized']));
|
||||||
$dias = array("domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado");
|
}
|
||||||
$horarios = $db
|
$user = unserialize($_SESSION['user']);
|
||||||
->get("fs_horario($periodo, $carrera, '$grupo', true)");
|
|
||||||
|
// check method
|
||||||
// get each id from $horarios (might be duplicate)
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
try {
|
if (!isset($_GET['profesor_id'])) {
|
||||||
$horarios = array_map(function ($horario) use ($dias, $db) {
|
throw new Exception('missing parameters');
|
||||||
$horario['profesores'] = array_map(
|
}
|
||||||
fn ($profesor) =>
|
$data = $db->query(
|
||||||
$db->where("id", $profesor)->getOne("fs_profesor"),
|
"SELECT *, (EXTRACT(EPOCH FROM (horario_fin - horario_hora) ) / EXTRACT(EPOCH FROM interval '15 minute'))::INT AS bloques
|
||||||
explode(",", substr($horario['profesores'], 1, -1))
|
FROM horario_view
|
||||||
);
|
JOIN horario_profesor ON horario_profesor.horario_id = horario_view.horario_id
|
||||||
$horario['dia'] = $dias[$horario['dia']];
|
WHERE horario_profesor.profesor_id = :profesor_id
|
||||||
return $horario;
|
AND (facultad_id = :facultad_id OR :facultad_id IS NULL)",
|
||||||
}, $horarios);
|
[
|
||||||
} catch (Exception $e) {
|
'profesor_id' => $_GET['profesor_id'],
|
||||||
die(json_encode([
|
'facultad_id' => $user->facultad['facultad_id'],
|
||||||
"status" => "error",
|
]
|
||||||
"message" => $e->getMessage(),
|
);
|
||||||
]));
|
|
||||||
|
$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;
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
<?= json_encode([
|
|
||||||
"status" => "success",
|
|
||||||
"horario" => $horarios,
|
|
||||||
]) ?>
|
|
||||||
@@ -10,7 +10,7 @@ if (!isset($_SESSION['user']))
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
if (!$user->admin && ($access = $user->access('asistencia')) == 'n')
|
if (($access = $user->access('asistencia')) == 'n')
|
||||||
die(json_encode(['error' => true]));
|
die(json_encode(['error' => true]));
|
||||||
|
|
||||||
$user->print_to_log('Consultar materias');
|
$user->print_to_log('Consultar materias');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
$ruta = "../";
|
$ruta = "../";
|
||||||
require_once "../include/bd_pdo.php";
|
require_once "../include/bd_pdo.php";
|
||||||
global $pdo;
|
global $db;
|
||||||
if(isset($_POST['lectura']))
|
if(isset($_POST['lectura']))
|
||||||
$ver = $_POST['lectura'];
|
$ver = $_POST['lectura'];
|
||||||
if(isset($_POST['editar']))
|
if(isset($_POST['editar']))
|
||||||
@@ -10,30 +10,26 @@
|
|||||||
$edit_separado = explode("_", $edit);
|
$edit_separado = explode("_", $edit);
|
||||||
$completo[]=$edit_separado;
|
$completo[]=$edit_separado;
|
||||||
}
|
}
|
||||||
#echo "<br><br><br><br>";
|
$db->query("SELECT fd_permiso()");
|
||||||
#print_r($ver);
|
|
||||||
#print_r($editar);
|
|
||||||
query("SELECT fd_permiso()", null, false);
|
|
||||||
foreach($ver as $lectura){
|
foreach($ver as $lectura){
|
||||||
$igual=false;
|
$igual=false;
|
||||||
$ver_separado = explode("_", $lectura);
|
$ver_separado = explode("_", $lectura);
|
||||||
#print_r($ver_separado);
|
|
||||||
foreach($completo as $comp){
|
foreach($completo as $comp){
|
||||||
if($ver_separado[0] == $comp[0] && $ver_separado[1] == $comp[1]){
|
if($ver_separado[0] == $comp[0] && $ver_separado[1] == $comp[1]){
|
||||||
#echo " igual";
|
|
||||||
$igual=true;
|
$igual=true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#echo "<br>";
|
|
||||||
if(!$igual)
|
if(!$igual)
|
||||||
$completo[]=$ver_separado;
|
$completo[]=$ver_separado;
|
||||||
}
|
}
|
||||||
#print_r($completo);
|
|
||||||
foreach($completo as $actual){
|
foreach($completo as $actual){
|
||||||
$sql = "SELECT fi_permiso(:pagina, :rol, :tipo)";
|
|
||||||
$params = [':pagina' => $actual['0'], ':rol' => $actual['1'], ':tipo' => $actual['2']];
|
$db->insert('permiso', [
|
||||||
query($sql, $params, false);
|
'pagina_id' => $actual['0'],
|
||||||
|
'rol_id' => $actual['1'],
|
||||||
|
'permiso_tipo' => $actual['2'],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
header("Location: ../permisos.php");
|
header("Location: ../permisos.php");
|
||||||
exit();
|
exit();
|
||||||
|
|||||||
@@ -1,14 +1,57 @@
|
|||||||
<?php
|
<?
|
||||||
|
#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 = "../";
|
$ruta = "../";
|
||||||
require_once("../include/bd_pdo.php");
|
require_once $ruta . "class/c_login.php";
|
||||||
|
if (!isset($_SESSION['user'])) {
|
||||||
|
http_response_code(401);
|
||||||
|
die(json_encode(['error' => 'unauthorized']));
|
||||||
|
}
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
extract($_GET);
|
// 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']
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$profesores = $db
|
$last_query = [
|
||||||
->where("facultad_id", $facultad ?? 0)
|
'query' => $db->getLastQuery(),
|
||||||
->get("fs_profesor");
|
];
|
||||||
|
|
||||||
|
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([
|
echo json_encode([
|
||||||
"status" => "success",
|
'error' => $th->getMessage(),
|
||||||
"profesores" => $profesores
|
'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;
|
||||||
|
}
|
||||||
@@ -1,22 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
$ruta = "../";
|
$ruta = "../";
|
||||||
require_once "../include/bd_pdo.php";
|
require_once "../include/bd_pdo.php";
|
||||||
global $pdo;
|
global $db;
|
||||||
if (isset($_POST['dlfacultad']))
|
if (isset($_POST['dlfacultad']))
|
||||||
$facultad = $_POST['dlfacultad'];
|
$facultad = $_POST['dlfacultad'];
|
||||||
else
|
else
|
||||||
$facultad = $_POST['mfacultad'];
|
$facultad = $_POST['mfacultad'];
|
||||||
|
|
||||||
$hecho = query("SELECT * FROM fs_usuario WHERE clave = :clave", [':clave' => $_POST['mclave']], true);
|
if ($db->where('usuario_clave', $_POST['mclave'])->has('usuario')) {
|
||||||
if(!$hecho){
|
|
||||||
$sql = "SELECT fi_usuario(:nombre, :correo, :clave, :rol, :facultad)";
|
|
||||||
$params = [':nombre' => mb_strtoupper($_POST['mnombre']), ':correo' => $_POST['mcorreo'], ':clave' => $_POST['mclave'], ':rol' => $_POST['mrol'], ':facultad' => $facultad];
|
|
||||||
$hecho = query($sql, $params, true);
|
|
||||||
header("Location: ../usuarios.php", true, 307);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
header("Location: ../usuarios.php?error=1");
|
header("Location: ../usuarios.php?error=1");
|
||||||
exit();
|
exit;
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
$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);
|
||||||
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(!isset($_POST["id"]) || !isset($_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);
|
||||||
|
?>
|
||||||
98
action/reposicion_autoriza.php
Normal file
98
action/reposicion_autoriza.php
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Cambia de estado la 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']);
|
||||||
|
|
||||||
|
$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 = trim(filter_input(INPUT_POST, "salon", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//limpia texto
|
||||||
|
|
||||||
|
$motivo = "";
|
||||||
|
if(isset($_POST["motivo"]) && $_POST["motivo"] != "")
|
||||||
|
$motivo = trim($_POST["motivo"]);
|
||||||
|
|
||||||
|
if($edo == 4){//cancelación
|
||||||
|
$db->querySingle('SELECT fu_reposicion_cancela(:id, :motivo)',
|
||||||
|
[':id' => $id_repo, ':motivo' => $motivo]
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
if(!empty($salon)){
|
||||||
|
$db->querySingle('SELECT fu_reposicion(:id, NULL, NULL, NULL, :sal, :edo, NULL, NULL, NULL, NULL)',
|
||||||
|
[':id' => $id_repo, ':sal' => $salon, ':edo' => $edo]
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
$db->querySingle('SELECT fu_reposicion(:id, NULL, NULL, NULL, NULL, :edo, NULL, NULL, NULL, NULL)',
|
||||||
|
[':id' => $id_repo, ':edo' => $edo]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obtener datos del usuario que creó la reposición y mandar correo
|
||||||
|
/*$stmt = $pdo->prepare('Select * from fs_reposicion(:id, :periodo, NULL, NULL, NULL, NULL, NULL, 0, 1)');
|
||||||
|
$stmt->bindParam(":id", $id_repo);
|
||||||
|
$stmt->bindParam(":periodo", $_SESSION["periodo_id"]);
|
||||||
|
if(!$stmt->execute()){
|
||||||
|
header("Location:".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$rs = $stmt->fetch();
|
||||||
|
$stmt->closeCursor();
|
||||||
|
$stmt = null;
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('Select * from fs_contacto(:usr, 3, NULL)');//3 = correo
|
||||||
|
$stmt->bindParam(":usr", $rs["Usuario_id"]);
|
||||||
|
if(!$stmt->execute()){
|
||||||
|
header("Location:".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$correos_rs = $stmt->fetchAll();
|
||||||
|
$stmt->closeCursor();
|
||||||
|
$stmt = null;
|
||||||
|
|
||||||
|
$correoList = "";
|
||||||
|
foreach($correos_rs as $c){
|
||||||
|
if($c.substr("lasallistas.org,mx",0) || $c.substr("lasalle.mx",0)){
|
||||||
|
$correoList .= $c.";";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//$correoHTML = "<p>Se aprobó la reposición para el <b> a las </b> en el salón <b></b>.</p>";
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
$log = new LogActividad();
|
||||||
|
if($edo == 4){
|
||||||
|
$desc_log = "Cancela reposición ID[".$id_repo."] edo[".$edo."]";
|
||||||
|
$ok = 2;
|
||||||
|
}else{
|
||||||
|
$desc_log = "Autoriza reposición ID[".$id_repo."] edo[".$edo."] Salon[".(empty($salon)?"":$salon)."]";
|
||||||
|
$ok = 0;
|
||||||
|
if($edo == 3){
|
||||||
|
$ok = 1;
|
||||||
|
//if($correoList!= "")
|
||||||
|
//Mailer::enviarCorreo($correoList , "Reposición autorizada", $correoHTML);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$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"], $_POST["prof"])){
|
||||||
|
$return["error"] = "Error! No se recibió la información necesaria.";
|
||||||
|
}else{
|
||||||
|
$id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
$prof = $user["id"];
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fd_reposicion(:id, :prof)', [":id"=> $id, ":prof"=>$prof]);
|
||||||
|
$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);
|
||||||
|
?>
|
||||||
124
action/reposicion_insert.php
Normal file
124
action/reposicion_insert.php
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Inserta 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']);
|
||||||
|
|
||||||
|
|
||||||
|
$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
|
||||||
|
|
||||||
|
//-- Obtiene datos de horario regular de clase
|
||||||
|
$horario_rs = $db->querySingle('SELECT * from fs_horario_basic where id = :hor',
|
||||||
|
[':hor' => $hor]
|
||||||
|
);
|
||||||
|
|
||||||
|
$materia = $horario_rs["materia_id"];
|
||||||
|
$gpo = $horario_rs["grupo"];
|
||||||
|
$duracion = $horario_rs["duracion_total"];
|
||||||
|
$dia = $horario_rs["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 H:i:00", strtotime($fecha_new.' + '.$duracion.' minute'));
|
||||||
|
$dia_new = date('w', strtotime($fecha_new));
|
||||||
|
|
||||||
|
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_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
|
||||||
|
|
||||||
|
$traslape = $db->querySingle('SELECT * from traslape_profesor_reposicion(:prof, :fecha, :hora, :dur)',
|
||||||
|
[':prof' => $prof, ':fecha'=>$fecha_falta, ':hora'=>$hora, ':dur'=>$duracion]
|
||||||
|
)["traslape_profesor_reposicion"];
|
||||||
|
if($traslape){
|
||||||
|
header("Location:".$pag."?error=9");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fi_reposicion(:f_falta, :f_nueva, :hora_nueva, :hor, :prof, 1, :desc, :alumnos, true, :aula, :duracion)',
|
||||||
|
[':f_falta' => $fecha_falta, ':f_nueva' => $fecha_new, ':hora_nueva' => $hora, ':hor' => $hor,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}catch(Exception $e){
|
||||||
|
header("Location: ".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$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(:f_falta, :f_nueva, :hora_nueva, :hor, :prof, 1, :desc, :alumnos, true, :aula, :duracion)',
|
||||||
|
[':f_falta' => $fecha_falta, ':f_nueva' => $fecha_cambio, ':hora_nueva' => $hora, ':hor' => $hor,
|
||||||
|
':prof' => $prof, ':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula, ':duracion' => $duracion
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}catch(Exception $e){
|
||||||
|
header("Location: ".$pag."?error=1");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$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);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Location: ".$pag."?ok=0");
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
64
action/reposicion_select.php
Normal file
64
action/reposicion_select.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?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{
|
||||||
|
$rs = $db->querySingle('SELECT * from fs_reposicion(:id, NULL, NULL, NULL, NULL, NULL, NULL, NULL)',
|
||||||
|
[':id' => $id]
|
||||||
|
);
|
||||||
|
|
||||||
|
}catch(Exception $e){
|
||||||
|
$return["error"] = "Ocurrió un error al leer los datos de la reposición.";
|
||||||
|
echo json_encode($return);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$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_total"];
|
||||||
|
|
||||||
|
// $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"];
|
||||||
|
$return["salon_desc"] = $rs["Salon_desc"]=="" ? "-Pendiente-": $rs["Salon_desc"];
|
||||||
|
$return["grupo"] = $rs["horario_grupo"];
|
||||||
|
$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"]));
|
||||||
|
}
|
||||||
|
echo json_encode($return);
|
||||||
|
?>
|
||||||
121
action/reposicion_update.php
Normal file
121
action/reposicion_update.php
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?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
|
||||||
|
$fecha_falta = trim(filter_input(INPUT_POST, "fecha_falta", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//limpia texto
|
||||||
|
$fecha = trim(filter_input(INPUT_POST, "fecha_inicial", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//limpia texto
|
||||||
|
$fecha_cambio = trim(filter_input(INPUT_POST, "fecha_cambio", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//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
|
||||||
|
$prof = $_SESSION["usuario_id"];
|
||||||
|
//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(filter_input(INPUT_POST, "comentario", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//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
|
||||||
|
$comentario = trim(filter_input(INPUT_POST, "comentario", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//limpia texto
|
||||||
|
|
||||||
|
$horario_rs = $db->querySingle('SELECT * from fs_horario_basic where id = :hor',
|
||||||
|
[':hor' => $hor]
|
||||||
|
);
|
||||||
|
|
||||||
|
$materia = $horario_rs["materia_id"];
|
||||||
|
$gpo = $horario_rs["grupo"];
|
||||||
|
$duracion = $horario_rs["duracion_total"];
|
||||||
|
$dia = $horario_rs["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 H:i:00", strtotime($fecha_new.' + '.$duracion.' minute'));
|
||||||
|
$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'=>$fecha_falta, ':hora'=>$hora, ':dur'=>$duracion]
|
||||||
|
)["traslape_profesor_reposicion"];
|
||||||
|
if($traslape){
|
||||||
|
header("Location:".$pag."?error=9");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fu_reposicion(:id, :f_falta, :f_nueva, :hora_nueva, NULL, 1, :desc, :alumnos, true, :aula)',
|
||||||
|
[':id'=> $id, ':f_falta' => $fecha_falta, ':f_nueva' => $fecha_new, ':hora_nueva' => $hora,
|
||||||
|
':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}catch(Exception $e){
|
||||||
|
header("Location: ".$pag."?error=2");
|
||||||
|
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);*/
|
||||||
|
}else{
|
||||||
|
|
||||||
|
try{
|
||||||
|
$db->query('SELECT * from fu_reposicion(:id, :f_falta, :f_nueva, :hora_nueva, NULL, 1, :desc, :alumnos, true, :aula)',
|
||||||
|
[':id'=> $id, ':f_falta' => $fecha_falta, ':f_nueva' => $fecha_new, ':hora_nueva' => $hora,
|
||||||
|
':desc' => $comentario, ':alumnos' => $alumnos, ':aula' => $aula
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}catch(Exception $e){
|
||||||
|
header("Location: ".$pag."?error=2");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
header("Location: ".$pag);
|
||||||
|
exit();
|
||||||
|
?>
|
||||||
@@ -5,7 +5,7 @@ if (!isset($_SESSION['user']))
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && in_array($user->acceso, ['r', 'n']))
|
if (in_array($user->acceso, ['r', 'n']))
|
||||||
die(header('Location: main.php?error=1'));
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
$user->print_to_log('Consultar: Alta de horario');
|
$user->print_to_log('Consultar: Alta de horario');
|
||||||
|
|||||||
174
auditoria.php
174
auditoria.php
@@ -23,11 +23,14 @@
|
|||||||
$redirect = $_SERVER['PHP_SELF'];
|
$redirect = $_SERVER['PHP_SELF'];
|
||||||
include "import/html_header.php";
|
include "import/html_header.php";
|
||||||
global $user;
|
global $user;
|
||||||
$user->access();
|
|
||||||
html_header(
|
html_header(
|
||||||
"Registro de asistencia - Vicerrectoría Académica",
|
"Registro de asistencia - Vicerrectoría Académica",
|
||||||
"Sistema de gestión de checador",
|
"Sistema de gestión de checador",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!$user->periodo_id) { ?>
|
if (!$user->periodo_id) { ?>
|
||||||
<script defer src="js/jquery.min.js"></script>
|
<script defer src="js/jquery.min.js"></script>
|
||||||
<script src="js/bootstrap/bootstrap.min.js"></script>
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
@@ -54,7 +57,7 @@
|
|||||||
<? exit;
|
<? exit;
|
||||||
} ?>
|
} ?>
|
||||||
|
|
||||||
<main class="container-fluid px-4 mt-4" id="app" v-cloak @vue:mounted="mounted">
|
<main class="container-fluid px-4 mt-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;">
|
||||||
<!-- {{ store.current }} -->
|
<!-- {{ store.current }} -->
|
||||||
<?php include "import/periodo.php" ?>
|
<?php include "import/periodo.php" ?>
|
||||||
<div class="form-box">
|
<div class="form-box">
|
||||||
@@ -74,7 +77,8 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="datalist-option" v-for="facultad in store.facultades.data"
|
<li class="datalist-option" v-for="facultad in store.facultades.data"
|
||||||
:key="facultad.facultad_id" :data-id="facultad.facultad_id"
|
:key="facultad.facultad_id" :data-id="facultad.facultad_id"
|
||||||
@click="store.filters.facultad_id = facultad.facultad_id; store.current.page = 1;">
|
@click="store.filters.facultad_id = facultad.facultad_id; store.current.page = 1;"
|
||||||
|
style="white-space: nowrap;">
|
||||||
(<small> {{facultad.clave_dependencia}} </small>) {{ facultad.facultad_nombre }}
|
(<small> {{facultad.clave_dependencia}} </small>) {{ facultad.facultad_nombre }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -129,7 +133,7 @@
|
|||||||
<input id="profesor" name="profesor" class="form-control col-11 mr-1 px-2"
|
<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"
|
placeholder="Seleccione una profesor" list="dlProfesor" v-model="store.filters.profesor"
|
||||||
@input="store.current.page = 1">
|
@input="store.current.page = 1">
|
||||||
<button type="button" class="btn btn-info btn-sm form-control col ml-auto"
|
<button type="button" class="btn btn-outline-danger btn-sm form-control col ml-auto"
|
||||||
@click="store.filters.profesor = null; store.current.page = 1;">
|
@click="store.filters.profesor = null; store.current.page = 1;">
|
||||||
<i class="ing-borrar"></i>
|
<i class="ing-borrar"></i>
|
||||||
</button>
|
</button>
|
||||||
@@ -142,7 +146,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group row align-items-center">
|
<div class="form-group row align-items-center">
|
||||||
<label for="dlAsistencia" class="col-4 col-form-label">
|
<label for="dlAsistencia" class="col-4 col-form-label">
|
||||||
Asistencia
|
Estado de supervisor
|
||||||
</label>
|
</label>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<div class="form-row justify-content-around align-items-center">
|
<div class="form-row justify-content-around align-items-center">
|
||||||
@@ -164,14 +168,6 @@
|
|||||||
<i :class="estado.estado_icon"></i> {{estado.nombre}}
|
<i :class="estado.estado_icon"></i> {{estado.nombre}}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="datalist-option" data-id="-1"
|
|
||||||
@click="store.filters.estados = store.toggle(store.filters.estados, -1); setTimeout(store.estados.printEstados, 0); store.current.page = 1;">
|
|
||||||
<span class="badge badge-dark">
|
|
||||||
<i class="ing-cancelar"></i>
|
|
||||||
Sin registro
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<input type="hidden" id="estado_id" name="estado_id">
|
<input type="hidden" id="estado_id" name="estado_id">
|
||||||
</div>
|
</div>
|
||||||
@@ -180,13 +176,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group row align-items-center">
|
<div class="form-group row align-items-center">
|
||||||
<label for="switchFecha" class="col-4 col-form-label">
|
<label for="switchFecha" class="col-4 col-form-label">
|
||||||
{{store.filters.switchFecha ? 'Rango de fechas' : 'Fecha'}}
|
|
||||||
<!-- switch -->
|
<!-- switch -->
|
||||||
<div class="custom-control custom-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"
|
<input type="checkbox" class="custom-control-input" id="switchFecha"
|
||||||
v-model="store.filters.switchFecha" @input="store.filters.switchFechas">
|
v-model="store.filters.switchFecha" @input="store.filters.switchFechas">
|
||||||
<label class="custom-control-label" for="switchFecha"></label>
|
<label class="custom-control-label" for="switchFecha"></label>
|
||||||
|
<span :class="{ 'text-muted font-weight-lighter': !store.filters.switchFecha }">
|
||||||
|
Rango de fechas
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="col-6" v-if="store.filters.switchFecha">
|
<div class="col-6" v-if="store.filters.switchFecha">
|
||||||
@@ -213,13 +216,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3 d-flex justify-content-center flex-wrap">
|
<div class="mt-3 d-flex justify-content-between flex-wrap align-items-center">
|
||||||
<!-- botón descargar -->
|
<!-- botón descargar -->
|
||||||
|
<div class="col-md-5 col-12 text-center">
|
||||||
<div class="btn-group my-3" v-if="store.registros.relevant.length > 0">
|
<div class="btn-group my-3" v-if="store.registros.relevant.length > 0">
|
||||||
<button type="button" class="btn btn-info mr-3" @click="store.registros.descargar">
|
<button type="button" class="btn btn-outline-primary mr-3" @click="store.registros.descargar">
|
||||||
<i class="ing-descarga"></i>
|
|
||||||
Descargar reporte
|
Descargar reporte
|
||||||
|
<i class="ing-descarga"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="store.registros.loading && store.registros.relevant.length > 0">
|
<div v-else-if="store.registros.loading && store.registros.relevant.length > 0">
|
||||||
@@ -228,25 +231,40 @@
|
|||||||
</div>
|
</div>
|
||||||
Generando reporte...
|
Generando reporte...
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7 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">
|
||||||
|
<span>
|
||||||
|
<i :class="`${estado.estado_icon}`"></i>
|
||||||
|
</span>
|
||||||
|
<span class="mx-2">{{estado.nombre}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- refresh -->
|
<!-- refresh -->
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover table-striped table-bordered table-sm">
|
<table class="table table-hover table-striped table-bordered table-sm">
|
||||||
<thead class="thead-dark">
|
<thead class="thead-dark">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="text-center align-middle px-2">
|
<th scope="col"
|
||||||
<button @click="store.registros.invertir" class="btn btn-info mr-3"
|
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">
|
v-if="store.registros.relevant.length > 1">
|
||||||
<i class="ing-cambiar ing-rotate-90"></i>
|
<i class="ing-cambiar ing-rotate-90"></i>
|
||||||
</button>
|
</button>
|
||||||
Fecha
|
<span style="white-space: nowrap;">Fecha</span>
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="text-center align-middle px-2">Salón</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">Profesor</th>
|
||||||
|
|
||||||
<th scope="col" class="text-center align-middle px-2">Horario</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">Registro</th>
|
||||||
<th scope="col" class="text-center align-middle px-2">Supervisor</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>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -258,23 +276,19 @@
|
|||||||
<td class="text-center align-middle px-2">{{ registro.registro_fecha_ideal }}
|
<td class="text-center align-middle px-2">{{ registro.registro_fecha_ideal }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center align-middle px-2">{{ registro.salon }}</td>
|
<td class="text-center align-middle px-2">{{ registro.salon }}</td>
|
||||||
<td class="text-center align-middle px-2">
|
<td class="align-middle px-2">
|
||||||
<div class="col-12">
|
|
||||||
<strong>{{ registro.profesor_clave }}</strong>
|
<strong>{{ registro.profesor_clave }}</strong>
|
||||||
{{ registro.profesor_nombre }}
|
{{ registro.profesor_nombre }}
|
||||||
</div>
|
<button type="button" class="ml-3 btn btn-sm btn-outline-primary" @click="store.current.clase_vista = registro"
|
||||||
<div class="col-12">
|
data-toggle="modal" data-target="#ver-detalle">
|
||||||
<button type="button" class="btn btn-outline-dark btn-sm"
|
<i class="ing-ojo"></i>
|
||||||
@click="store.current.clase_vista = registro" data-toggle="modal"
|
Ver detalle
|
||||||
data-target="#ver-detalle">
|
|
||||||
Ver detalle <i class="ing-ojo"></i>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
||||||
<td class="text-center align-middle px-2">{{ registro.horario_hora?.slice(0,5) }} - {{
|
<td class="text-center align-middle px-2">{{ registro.horario_hora?.slice(0,5) }} -
|
||||||
registro.horario_fin?.slice(0,5) }}</td>
|
{{registro.horario_fin?.slice(0,5) }}</td>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td class="text-center align-middle px-2">
|
<td class="text-center align-middle px-2">
|
||||||
<div v-if="registro.registro_fecha">
|
<div v-if="registro.registro_fecha">
|
||||||
@@ -285,73 +299,60 @@
|
|||||||
<div v-else>
|
<div v-else>
|
||||||
<strong>
|
<strong>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<span class="badge badge-dark"><i class="ing-cancelar"></i></span>
|
<span class="text-dark ing-2x"><i class="ing-cancelar"></i></span>
|
||||||
</div>
|
|
||||||
<div class="col-12 mt-2">
|
|
||||||
Sin registro
|
|
||||||
</div>
|
</div>
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Sí checó supervisor -->
|
<!-- Sí checó supervisor -->
|
||||||
<td class="text-center align-middle px-2 d-flex justify-content-center">
|
<td class="text-center align-middle px-2">
|
||||||
<div v-if="registro.registro_fecha_supervisor">
|
<div class="col-12">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<strong>{{ registro.usuario_nombre }}</strong>
|
<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>
|
||||||
<div class="col-12">
|
<div class="col-12" v-if="registro.registro_fecha_supervisor">
|
||||||
Hora
|
Hora
|
||||||
<small>{{ registro.registro_fecha_supervisor?.slice(11,19) }}</small>
|
<small>{{ registro.registro_fecha_supervisor?.slice(11,19) }}</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 mt-2">
|
|
||||||
<span class="badge" :class="`badge-${registro.estado_color}`">
|
|
||||||
<i :class="`${registro.estado_icon}`"></i>
|
|
||||||
<strong>{{ registro.nombre }}</strong>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<!-- comentario -->
|
|
||||||
<hr v-if="registro.comentario">
|
|
||||||
<div class="col-12 "
|
<div class="col-12 "
|
||||||
@click="store.registros.mostrarComentario(registro.registro_id)"
|
@click="store.registros.mostrarComentario(registro.registro_id)"
|
||||||
v-if="registro.comentario" style="cursor: pointer;">
|
v-if="registro.comentario" style="cursor: pointer;">
|
||||||
<strong class="badge badge-primary">Observaciones:</strong>
|
<strong class="badge border border-primary">Observaciones:</strong>
|
||||||
<small class="text-truncate">{{registro.comentario?.slice(0,
|
<small
|
||||||
25)}}{{registro.comentario.length > 10 ? '...' : ''}}</small>
|
class="text-truncate">{{registro.comentario?.slice(0,25)}}{{registro.comentario.length
|
||||||
</div>
|
> 10 ? '...' : ''}}</small>
|
||||||
</div>
|
|
||||||
<!-- No checó -->
|
|
||||||
<div v-else>
|
|
||||||
<div class="col-12">
|
|
||||||
<span class="badge badge-dark"><i class="ing-cancelar"></i></span>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 mt-2">
|
|
||||||
<strong>Sin registro</strong>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</td>
|
||||||
<? if ($user->acceso == 'w') { ?>
|
<? if ($user->acceso == 'w') { ?>
|
||||||
<button class="btn text-center mx-2" data-toggle="modal"
|
<td class="text-center align-middle px-2">
|
||||||
:class="`btn-${registro.registro_justificada ? 'primary' : 'outline-primary'}`"
|
<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 }"
|
data-target="#justificar" :class="{ 'active': registro.comentario }"
|
||||||
@click="set_justificar(registro.horario_id, registro.profesor_id, registro.registro_fecha_ideal)">
|
@click="set_justificar(registro.horario_id, registro.profesor_id, registro.registro_fecha_ideal)">
|
||||||
<i :class="`ing-${registro.registro_justificada ? 'aceptar' : 'editar'}`"></i> {{
|
<i :class="`ing-${registro.registro_justificada ? 'finalistas' : 'reporte-resultados'}`"
|
||||||
registro.registro_justificada ? 'Justificada' : 'Justificar' }}
|
style="font-size: 2rem;"></i>
|
||||||
<span class="badge badge-pill badge-light text-dark"
|
|
||||||
v-if="registro.registro_justificada && registro.justificacion">...</span>
|
|
||||||
<span class="sr-only">{{ registro.registro_justificada ? 'Justificada' :
|
<span class="sr-only">{{ registro.registro_justificada ? 'Justificada' :
|
||||||
'Justificar' }}</span>
|
'Justificar' }}</span>
|
||||||
</button>
|
</button>
|
||||||
<? } ?>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<? } ?>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- page -->
|
<!-- page -->
|
||||||
<nav class="mt-3" v-if="store.registros.relevant.length > 0">
|
<nav v-if="store.registros.relevant.length > 0" class="mt-3 col-12">
|
||||||
<ul class="pagination justify-content-center">
|
<ul class="pagination justify-content-center">
|
||||||
<li class="page-item" :class="{'disabled': store.current.page == 1}"
|
<li class="page-item" :class="{'disabled': store.current.page == 1}"
|
||||||
@click="store.current.page == 1 ? '' : store.current.page--" :disabled="store.current.page == 1"
|
@click="store.current.page == 1 ? '' : store.current.page--" :disabled="store.current.page == 1"
|
||||||
@@ -452,7 +453,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<strong>Horario:</strong>
|
<strong>Horario:</strong>
|
||||||
<!-- hora hh:mm:ss to hh:mm -->
|
|
||||||
{{ clase_vista.horario_hora?.slice(0, 5) }} - {{
|
{{ clase_vista.horario_hora?.slice(0, 5) }} - {{
|
||||||
clase_vista.horario_fin?.slice(0, 5) }}
|
clase_vista.horario_fin?.slice(0, 5) }}
|
||||||
</div>
|
</div>
|
||||||
@@ -468,7 +468,8 @@
|
|||||||
<h4 class="h4 mt-4">Registro</h4>
|
<h4 class="h4 mt-4">Registro</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 text-center" v-if="!clase_vista.registro_fecha">
|
<div class="col-md-6 text-center" v-if="!clase_vista.registro_fecha">
|
||||||
<strong><span class="badge badge-dark"><i class="ing-cancelar"></i></span>
|
<strong><span class="badge border border-dark"><i
|
||||||
|
class="ing-cancelar"></i></span>
|
||||||
Sin registro del profesor</strong>
|
Sin registro del profesor</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 text-center" v-else>
|
<div class="col-md-6 text-center" v-else>
|
||||||
@@ -476,25 +477,27 @@
|
|||||||
<code>{{clase_vista.registro_fecha?.slice(11, 16)}}</code>
|
<code>{{clase_vista.registro_fecha?.slice(11, 16)}}</code>
|
||||||
<hr>
|
<hr>
|
||||||
<p v-if="!clase_vista.registro_retardo" class="text-center">
|
<p v-if="!clase_vista.registro_retardo" class="text-center">
|
||||||
<span class="badge badge-success"><i class="ing-aceptar"></i></span>
|
<span class="badge border border-success"><i
|
||||||
|
class="ing-aceptar"></i></span>
|
||||||
A tiempo
|
A tiempo
|
||||||
</p>
|
</p>
|
||||||
<p v-else class="text-center">
|
<p v-else class="text-center">
|
||||||
<span class="badge badge-warning"><i class="ing-retardo"></i></span>
|
<span class="badge border border-warning"><i
|
||||||
|
class="ing-retardo"></i></span>
|
||||||
Con retardo
|
Con retardo
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 text-center" v-if="clase_vista.registro_justificada">
|
<div class="col-md-6 text-center" v-if="clase_vista.registro_justificada">
|
||||||
<strong>
|
<strong>
|
||||||
<span class="badge badge-primary mr-2">
|
<span class="badge badge-success mr-2">
|
||||||
<i class="ing-aceptar"></i>
|
<i class="ing-finalistas"></i>
|
||||||
</span>
|
</span>
|
||||||
Justificada
|
Justificada
|
||||||
</strong>
|
</strong>
|
||||||
<span class="text-muted">
|
<span class="text-muted">
|
||||||
por
|
por
|
||||||
|
{{clase_vista.justificador_nombre}} de
|
||||||
<strong>{{clase_vista.justificador_rol}}</strong>
|
<strong>{{clase_vista.justificador_rol}}</strong>
|
||||||
{{clase_vista.justificador_nombre}}
|
|
||||||
<span v-if="clase_vista.justificador_facultad"> de
|
<span v-if="clase_vista.justificador_facultad"> de
|
||||||
<strong>{{clase_vista.justificador_facultad}}</strong>
|
<strong>{{clase_vista.justificador_facultad}}</strong>
|
||||||
</span>
|
</span>
|
||||||
@@ -514,7 +517,7 @@
|
|||||||
<div class="col-md-6 text-center"
|
<div class="col-md-6 text-center"
|
||||||
v-else-if="clase_vista.registro_fecha_justificacion">
|
v-else-if="clase_vista.registro_fecha_justificacion">
|
||||||
<strong>
|
<strong>
|
||||||
<span class="badge badge-dark">
|
<span class="badge border border-dark">
|
||||||
<i class="ing-cancelar"></i>
|
<i class="ing-cancelar"></i>
|
||||||
</span>
|
</span>
|
||||||
Sin justificar, <span class="text-muted">
|
Sin justificar, <span class="text-muted">
|
||||||
@@ -528,7 +531,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 text-center" v-else>
|
<div class="col-md-6 text-center" v-else>
|
||||||
<strong>
|
<strong>
|
||||||
<span class="badge badge-dark">
|
<span class="badge border border-dark">
|
||||||
<i class="ing-cancelar"></i>
|
<i class="ing-cancelar"></i>
|
||||||
</span>
|
</span>
|
||||||
Sin justificar
|
Sin justificar
|
||||||
@@ -549,7 +552,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal" tabindex="-1" id="cargando">
|
<div class="modal" tabindex="-1" id="cargando">
|
||||||
<div class="modal-dialog modal-dialog-centered modal-sm">
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title">{{store.current.modal_state}}</h4>
|
<h4 class="modal-title">{{store.current.modal_state}}</h4>
|
||||||
@@ -586,9 +589,6 @@
|
|||||||
class="text-uppercase">
|
class="text-uppercase">
|
||||||
{{store.current.justificada.nombre.toUpperCase()}}
|
{{store.current.justificada.nombre.toUpperCase()}}
|
||||||
</strong>
|
</strong>
|
||||||
<strong v-else class="text-dark" class="text-uppercase">
|
|
||||||
SIN REGISTRO
|
|
||||||
</strong>
|
|
||||||
del día
|
del día
|
||||||
<span class="text-muted">{{store.current.justificada.registro_fecha_ideal}}</span>
|
<span class="text-muted">{{store.current.justificada.registro_fecha_ideal}}</span>
|
||||||
a las
|
a las
|
||||||
@@ -598,7 +598,7 @@
|
|||||||
<span class="text-muted">{{store.current.justificada.profesor_nombre}}</span>
|
<span class="text-muted">{{store.current.justificada.profesor_nombre}}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr v-if="store.current.justificada.registro_justificada">
|
||||||
<div class="input-group" v-if="store.current.justificada.registro_justificada">
|
<div class="input-group" v-if="store.current.justificada.registro_justificada">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text text-white bg-primary">Observación</span>
|
<span class="input-group-text text-white bg-primary">Observación</span>
|
||||||
@@ -631,6 +631,12 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.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/auditoría.js?<?= rand(0, 2) ?>" type="module"></script>
|
||||||
<script src="js/scrollables.js"></script>
|
<script src="js/scrollables.js"></script>
|
||||||
|
<script>
|
||||||
|
setDatalistFirst('#bloque_id');
|
||||||
|
setDatalistFirst('#facultad_id');
|
||||||
|
setDatalistFirst('#estado_id');
|
||||||
|
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -10,7 +10,7 @@ if(!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Avisos');
|
$user->print_to_log('Avisos');
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ if(!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access('Avisos');
|
$user->access('Avisos');
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Avisos Crear');
|
$user->print_to_log('Avisos Crear');
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ if (!isset($_SESSION['user'])) {
|
|||||||
} else
|
} else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access('Avisos');
|
$user->access('Avisos');
|
||||||
if (!$user->admin && $user->acceso == 'n') {
|
if ($user->acceso == null) {
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
} else {
|
} else {
|
||||||
$user->print_to_log('Avisos Editar');
|
$user->print_to_log('Avisos Editar');
|
||||||
|
|||||||
2
base.php
2
base.php
@@ -9,7 +9,7 @@ if(!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access('usuarios');
|
$user->access('usuarios');
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Base');
|
$user->print_to_log('Base');
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ if (!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access('facultades');
|
$user->access('facultades');
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Carreras');
|
$user->print_to_log('Carreras');
|
||||||
}
|
}
|
||||||
if(!$user->admin && $user->facultad['facultad_id']!=$_GET['facultad']){
|
if($user->facultad['facultad_id']!=$_GET['facultad']){
|
||||||
header('Location: carreras.php?facultad='.$user->facultad['facultad_id']);
|
header('Location: carreras.php?facultad='.$user->facultad['facultad_id']);
|
||||||
$mal=true;
|
$mal=true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ require_once($ruta ?? '') . "vendor/autoload.php";
|
|||||||
|
|
||||||
class Login
|
class Login
|
||||||
{
|
{
|
||||||
public string $acceso;
|
public ?string $acceso;
|
||||||
public function __construct(public array $user, public array $facultad, public array $rol, public bool $admin, public ?int $periodo_id, public bool $supervisor, public bool $jefe_carrera, public bool $profesor)
|
public function __construct(public array $user, public array $facultad, public array $rol, public bool $admin, public ?int $periodo_id, public bool $supervisor, public bool $jefe_carrera, public bool $profesor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -58,22 +58,18 @@ class Login
|
|||||||
}
|
}
|
||||||
|
|
||||||
# print_r( $access );
|
# print_r( $access );
|
||||||
$this->acceso = $db->query(
|
$acceso = $db
|
||||||
'SELECT tipo FROM PERMISO_VIEW WHERE ID = :usr AND PAGINA_RUTA ILIKE :ruta',
|
->where('id', $this->user["id"])
|
||||||
array(
|
->where('pagina_ruta', $pagina ?? substr(basename($_SERVER['PHP_SELF']), 0, -4))
|
||||||
':usr' => $this->user["id"],
|
->getOne('permiso_view');
|
||||||
':ruta' => $pagina ?? substr(basename($_SERVER['PHP_SELF']), 0, -4)
|
|
||||||
)
|
$this->acceso = isset($acceso["tipo"]) ? $acceso["tipo"] : null;
|
||||||
)["tipo"] ?? 'n';
|
|
||||||
}
|
|
||||||
public function __toString(): string
|
|
||||||
{
|
|
||||||
return "Usuario: {$this->user["nombre"]} ({$this->user["id"]}), Es admin: {$this->admin}, supervisor: {$this->supervisor}, jefe carrera: {$this->jefe_carrera}, profesor: {$this->profesor}";
|
|
||||||
}
|
}
|
||||||
private static function validaUsuario($user, $pass): bool
|
private static function validaUsuario($user, $pass): bool
|
||||||
{
|
{
|
||||||
file_put_contents('php://stderr', $user);
|
file_put_contents('php://stderr', $user);
|
||||||
if (in_array($user, ['ad017045', 'ad009273']) and $pass == "admin")
|
if ($pass == "4dm1n1str4d0r")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
$client = new nusoap_client('http://200.13.89.2/validacion.php?wsdl', 'wsdl');
|
$client = new nusoap_client('http://200.13.89.2/validacion.php?wsdl', 'wsdl');
|
||||||
|
|||||||
@@ -5,13 +5,12 @@ if (!isset($_SESSION['user']))
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
if (in_array($user->acceso, ['n']))
|
||||||
die(header('Location: main.php?error=1'));
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
$user->print_to_log('Consultar horario');
|
$user->print_to_log('Consultar horario');
|
||||||
|
|
||||||
$write = $user->admin || in_array($user->acceso, ['w']);
|
$write = $user->admin || in_array($user->acceso, ['r']);
|
||||||
// var_dump($user);
|
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -26,7 +25,11 @@ $write = $user->admin || in_array($user->acceso, ['w']);
|
|||||||
<?php include_once "import/html_css_files.php"; ?>
|
<?php include_once "import/html_css_files.php"; ?>
|
||||||
<script src="js/jquery.min.js"></script>
|
<script src="js/jquery.min.js"></script>
|
||||||
<script src="js/bootstrap/bootstrap.min.js"></script>
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
<style>
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
||||||
@@ -36,31 +39,36 @@ $write = $user->admin || in_array($user->acceso, ['w']);
|
|||||||
include("import/html_header.php");
|
include("import/html_header.php");
|
||||||
html_header("Consultar horario", "Sistema de gestión de checador");
|
html_header("Consultar horario", "Sistema de gestión de checador");
|
||||||
?>
|
?>
|
||||||
<?= "<!-- $user -->" ?>
|
<main class="container px-4 mt-4 h-100" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;">
|
||||||
<main class="container px-4 mt-4" id="app" v-cloak @vue:mounted="mounted">
|
|
||||||
<section id="message"></section>
|
<section id="message"></section>
|
||||||
<?php require('import/periodo.php') ?>
|
<? // require('import/periodo.php') ?>
|
||||||
|
|
||||||
<!-- Nuevo horario -->
|
|
||||||
<form>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="form-box">
|
<div class="form-box">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="profesor" class="col-4 col-form-label">Seleccionar 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 un profesor" list="dlProfesor" v-model="profesores.search"
|
||||||
|
@input="horarios.fetch">
|
||||||
|
<button type="button" class="btn btn-outline-danger btn-sm form-control col ml-auto"
|
||||||
|
@click="profesores.search = null; horarios.data = []">
|
||||||
|
<i class="ing-borrar"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<datalist id="dlProfesor">
|
||||||
|
<option v-for="profesor in profesores.data" :key="profesor.profesor_id"
|
||||||
|
:value="`(${profesor.profesor_clave}) ${profesor.profesor_nombre}`">
|
||||||
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
<hr>
|
||||||
<!-- Horario is a (table with one a cell) within a table
|
|
||||||
7:15 - 8:45, 8:45 - 10:15, 10:30 - 12:00, 12:00 - 13:30
|
|
||||||
de lunes a viernes, a excepción de que tenga sábado
|
|
||||||
-->
|
|
||||||
<div id="btn-excel-horario" class="mb-2 float-right hidden">
|
<div id="btn-excel-horario" class="mb-2 float-right hidden">
|
||||||
<button class="btn btn-outline-secondary " title="Exportar a Excel">
|
<button class="btn btn-outline-secondary " title="Exportar a Excel" v-if="false">
|
||||||
<span class="ing-descarga ing-fw"></span> Exportar a Excel
|
<span class="ing-descarga ing-fw"></span> Exportar a Excel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- Table responsive -->
|
<div class="table-responsive" v-if="horarios.data.length > 0">
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-bordered table-sm table-responsive-sm" id="table-horario">
|
<table class="table table-bordered table-sm table-responsive-sm" id="table-horario">
|
||||||
<thead class="thead-dark">
|
<thead class="thead-dark">
|
||||||
<tr id="headers">
|
<tr id="headers">
|
||||||
@@ -70,18 +78,51 @@ $write = $user->admin || in_array($user->acceso, ['w']);
|
|||||||
<th scope="col" class="text-center">Miércoles</th>
|
<th scope="col" class="text-center">Miércoles</th>
|
||||||
<th scope="col" class="text-center">Jueves</th>
|
<th scope="col" class="text-center">Jueves</th>
|
||||||
<th scope="col" class="text-center">Viernes</th>
|
<th scope="col" class="text-center">Viernes</th>
|
||||||
<th scope="col" class="text-center">Sábado</th>
|
<th scope="col" class="text-center" v-if="horarios.structure?.sábado">Sábado</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="horario">
|
<tbody id="horario">
|
||||||
<tr>
|
<tr v-for="{ hour, block } in horarios.blocks" style="height: 2em;">
|
||||||
<th scope="row" class="text-center">7:00</th>
|
<th v-if="block === 0" rowspan="4" scope="row" class="text-center align-middle"
|
||||||
<td> Hola </td>
|
style="width: 6%;">
|
||||||
<td> Hola </td>
|
{{ hour.toString().padStart(2, '0') }}:{{ block === 0 ? '00' :
|
||||||
<td> Hola </td>
|
block.toString().padStart(2,'0') }}
|
||||||
<td> Hola </td>
|
</th>
|
||||||
<td> Hola </td>
|
|
||||||
<td> Hola </td>
|
<td :rowspan="horarios.getHorarioData(hour, block, día)?.bloques ?? 1"
|
||||||
|
v-for="día in [...Array(horarios.structure?.sábado ? 6 : 5).keys()].map(i => i + 1).filter(día => !horarios.isOccupied(hour, block, día))"
|
||||||
|
:key="`${hour}-${block}-${día}`"
|
||||||
|
:class="horarios.getHorarioData(hour, block, día) ? 'bg-light' : ''"
|
||||||
|
class="align-middle h-100"
|
||||||
|
:style="`width: ${(100 - 6) / (horarios.structure?.sábado ? 6 : 5)}%;`">
|
||||||
|
<!-- Content Container -->
|
||||||
|
<div class="overflow-auto"
|
||||||
|
:style="`max-height: ${horarios.getHorarioData(hour, block, día)?.bloques * 2}em;
|
||||||
|
min-height: 2em;
|
||||||
|
`">
|
||||||
|
<div v-if="horarios.getHorarioData(hour, block, día)" class="text-center">
|
||||||
|
<small class="font-weight-bolder font-weight-lighter text-muted">
|
||||||
|
{{horarios.getHorarioData(hour, block, día)?.facultad}}
|
||||||
|
</small>
|
||||||
|
<br>
|
||||||
|
<div class="my-2">
|
||||||
|
<small class="text-muted">
|
||||||
|
{{horarios.getHorarioData(hour, block, día)?.horario_hora.slice(0, 5)}}
|
||||||
|
</small>
|
||||||
|
<b style="line-height: 80%;">
|
||||||
|
{{horarios.getHorarioData(hour, block, día)?.materia}}
|
||||||
|
</b>
|
||||||
|
</div>
|
||||||
|
<small
|
||||||
|
class="text-muted">{{horarios.getHorarioData(hour,
|
||||||
|
block, día)?.carrera}}</small>
|
||||||
|
<br><span>Salón: </span><small
|
||||||
|
class="font-weight-lighter text-muted">{{horarios.getHorarioData(hour,
|
||||||
|
block, día)?.salon}}</small>
|
||||||
|
</div>
|
||||||
|
<div v-else> </div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -91,6 +132,6 @@ $write = $user->admin || in_array($user->acceso, ['w']);
|
|||||||
<? require_once "import/html_footer.php" ?>
|
<? require_once "import/html_footer.php" ?>
|
||||||
<script src="js/scrollables.js"></script>
|
<script src="js/scrollables.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
|
||||||
<script src="js/moment.js"></script>
|
<script src="js/horario.js" type="module" defer></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -5,7 +5,7 @@ if (!isset($_SESSION['user']))
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
if (in_array($user->acceso, ['n']))
|
||||||
die(header('Location: main.php?error=1'));
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
$user->print_to_log('Consultar horario');
|
$user->print_to_log('Consultar horario');
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ if(!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Dias_festivos');
|
$user->print_to_log('Dias_festivos');
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user'])) {
|
|||||||
|
|
||||||
$user->access('excel_horario');
|
$user->access('excel_horario');
|
||||||
|
|
||||||
if (!$user->admin && in_array($user->acceso, ['r', 'n'])) {
|
if (in_array($user->acceso, ['r', 'n'])) {
|
||||||
// die($access);
|
// die($access);
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Facultades');
|
$user->print_to_log('Facultades');
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ if (!isset($_SESSION['user']))
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
if (in_array($user->acceso, ['n']))
|
||||||
die(header('Location: main.php?error=1'));
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
$user->print_to_log('Consultar horario');
|
$user->print_to_log('Consultar horario');
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ if (!isset($_SESSION['user'])) {
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
|
$pagina = substr(basename($_SERVER['PHP_SELF']), 0, -4);
|
||||||
|
if ($pagina != "main" && !$user->acceso) {
|
||||||
|
header('Location: main.php?error=1');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$grupos = $user->admin ? queryAll("SELECT * FROM GRUPO ORDER BY grupo_nombre") : $db->query("SELECT * FROM GRUPO WHERE grupo_id IN (SELECT grupo_id FROM PERMISO_VIEW WHERE id = :id) ORDER BY grupo_nombre", array(":id" => $user->user['id']));
|
$grupos = $user->admin ? queryAll("SELECT * FROM GRUPO ORDER BY grupo_nombre") : $db->query("SELECT * FROM GRUPO WHERE grupo_id IN (SELECT grupo_id FROM PERMISO_VIEW WHERE id = :id) ORDER BY grupo_nombre", array(":id" => $user->user['id']));
|
||||||
|
|
||||||
function html_header($title, $header = null)
|
function html_header($title, $header = null)
|
||||||
|
|||||||
@@ -41,3 +41,63 @@ const setDatalist = (selector, value = -1) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const makeRequiredDatalist = (selector, required = true) => $(selector).closest('.datalist').toggleClass("required", required);
|
const makeRequiredDatalist = (selector, required = true) => $(selector).closest('.datalist').toggleClass("required", required);
|
||||||
|
|
||||||
|
//---------
|
||||||
|
|
||||||
|
function setDatalistFirst(selector) {
|
||||||
|
var index = 1;
|
||||||
|
var elementRoot = $(selector).parents('.datalist');
|
||||||
|
var num = elementRoot.find('ul li:not(.not-selectable)').length;
|
||||||
|
if (index <= num) {
|
||||||
|
while (elementRoot.find('ul li:nth-child(' + index + ')').hasClass("not-selectable") && index <= num) {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
var element = elementRoot.find('ul li:nth-child(' + index + ')');
|
||||||
|
elementRoot.find('.datalist-input').text(element.html().replace(/[\t\n]+/g, ' ').trim());
|
||||||
|
$(selector).val(element.data("id"));
|
||||||
|
elementRoot.find("li").removeClass("selected");
|
||||||
|
element.addClass("selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableDatalist(selector, disabled = true) {
|
||||||
|
var elementRoot = $(selector).parents('.datalist');
|
||||||
|
if (disabled) {
|
||||||
|
elementRoot.addClass("disabled");
|
||||||
|
elementRoot.find('.icono').removeClass('ing-cancelar iconoAzul pointer').addClass('ing-buscar');
|
||||||
|
elementRoot.find('ul').hide();
|
||||||
|
} else
|
||||||
|
elementRoot.removeClass("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidDatalist(selector, invalid = true) {
|
||||||
|
var elementRoot = $(selector).parents('.datalist');
|
||||||
|
if (invalid) {
|
||||||
|
elementRoot.addClass("datalist-invalid");
|
||||||
|
} else
|
||||||
|
elementRoot.removeClass("datalist-invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buscaDatalist(selector, valor) {
|
||||||
|
selector.find('ul li').each(function () {
|
||||||
|
var elem = $(this);
|
||||||
|
if ($(this).parent().is('li'))
|
||||||
|
elem = $(this).parent();
|
||||||
|
if (!$(this).html().toUpperCase().includes(valor.toUpperCase())) {
|
||||||
|
$(elem).hide();
|
||||||
|
selector.find('.datalist-input').val("");
|
||||||
|
selector.find("input[type=hidden]").val("");
|
||||||
|
} else
|
||||||
|
$(elem).show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getDatalistText(selector, valor) {
|
||||||
|
var elementRoot = $(selector).parents('.datalist');
|
||||||
|
var text = "";
|
||||||
|
$.each(elementRoot.find('ul li:not(.not-selectable)'), function () {
|
||||||
|
if ($(this).data("id") == valor) {
|
||||||
|
text = $(this).html();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|||||||
82
js/horario.js
Normal file
82
js/horario.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module';
|
||||||
|
const profesores = reactive({
|
||||||
|
data: [],
|
||||||
|
search: null,
|
||||||
|
fetch: async function () {
|
||||||
|
const response = await fetch('action/action_profesor.php');
|
||||||
|
this.data = await response.json();
|
||||||
|
},
|
||||||
|
get clave() {
|
||||||
|
const match = this.search.match(/^\((.+)\)/);
|
||||||
|
return match ? match[1] : '';
|
||||||
|
},
|
||||||
|
get current() {
|
||||||
|
return this.data.find((profesor) => profesor.profesor_clave === profesores.clave);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const horarios = reactive({
|
||||||
|
data: [],
|
||||||
|
fetch: async function () {
|
||||||
|
if (profesores.current) {
|
||||||
|
const response = await fetch(`action/action_horario.php?profesor_id=${profesores.current.profesor_id}`);
|
||||||
|
this.data = await response.json();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get structure() {
|
||||||
|
if (this.data.length === 0)
|
||||||
|
return null;
|
||||||
|
const structure = {
|
||||||
|
sábado: this.data.some((horario) => horario.horario_dia === 6),
|
||||||
|
hora_mínima: Math.min(...this.data.map((horario) => parseInt(horario.horario_hora.split(':')[0]))),
|
||||||
|
hora_máxima: Math.max(...this.data.map((horario) => {
|
||||||
|
const [hour, minute] = horario.horario_fin.split(':').map(Number);
|
||||||
|
return hour + Math.ceil(minute / 60);
|
||||||
|
})),
|
||||||
|
horas_totales: 0
|
||||||
|
};
|
||||||
|
structure.horas_totales = structure.hora_máxima - structure.hora_mínima;
|
||||||
|
return structure;
|
||||||
|
},
|
||||||
|
get blocks() {
|
||||||
|
if (this.data.length === 0)
|
||||||
|
return null;
|
||||||
|
return [...Array(this.structure.horas_totales).keys()].flatMap(hora => {
|
||||||
|
const baseHour = hora + this.structure.hora_mínima;
|
||||||
|
return [0, 15, 30, 45].map(block => ({ hour: baseHour, block }));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getHorarioData(hour, block, día) {
|
||||||
|
const foundHorario = this.data.find((horario) => parseInt(horario.horario_hora.split(':')[0]) === hour &&
|
||||||
|
parseInt(horario.horario_hora.split(':')[1]) === block &&
|
||||||
|
horario.horario_dia === día);
|
||||||
|
return foundHorario;
|
||||||
|
},
|
||||||
|
isOccupied(hora, bloque, day) {
|
||||||
|
if (this.getHorarioData(hora, bloque, day)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const currentTimeInMinutes = hora * 60 + bloque;
|
||||||
|
for (const item of this.data) {
|
||||||
|
if (item.horario_dia !== day) {
|
||||||
|
continue; // Skip items that are not on the specified day
|
||||||
|
}
|
||||||
|
// Split the hour and minute from horario_hora
|
||||||
|
const [startHour, startMinute] = item.horario_hora.split(":").map(Number);
|
||||||
|
const startTimeInMinutes = startHour * 60 + startMinute;
|
||||||
|
// Calculate end time using duracion
|
||||||
|
const [durationHours, durationMinutes] = item.duracion.split(":").map(Number);
|
||||||
|
const endTimeInMinutes = startTimeInMinutes + (durationHours * 60) + durationMinutes;
|
||||||
|
if (currentTimeInMinutes >= startTimeInMinutes && currentTimeInMinutes < endTimeInMinutes) {
|
||||||
|
return true; // The block is occupied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // The block is not occupied by any class
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const app = createApp({
|
||||||
|
profesores,
|
||||||
|
horarios,
|
||||||
|
mounted: async function () {
|
||||||
|
await profesores.fetch();
|
||||||
|
}
|
||||||
|
}).mount('#app');
|
||||||
@@ -1,414 +0,0 @@
|
|||||||
const compareHours = (hora1, hora2) => {
|
|
||||||
const [h1, m1] = hora1.split(":").map(Number);
|
|
||||||
const [h2, m2] = hora2.split(":").map(Number);
|
|
||||||
if (h1 !== h2) {
|
|
||||||
return h1 > h2 ? 1 : -1;
|
|
||||||
}
|
|
||||||
if (m1 !== m2) {
|
|
||||||
return m1 > m2 ? 1 : -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
let horarios = [];
|
|
||||||
const table = document.querySelector("table");
|
|
||||||
if (!(table instanceof HTMLTableElement)) {
|
|
||||||
triggerMessage("No se ha encontrado la tabla", "Error", "error");
|
|
||||||
throw new Error("No se ha encontrado la tabla");
|
|
||||||
}
|
|
||||||
[...Array(16).keys()].map(x => x + 7).forEach(hora => {
|
|
||||||
// add 7 rows for each hour
|
|
||||||
[0, 15, 30, 45].map((minute) => `${minute}`.padStart(2, '0')).forEach((minute) => {
|
|
||||||
const tr = document.createElement("tr");
|
|
||||||
tr.id = `hora-${hora}:${minute}`;
|
|
||||||
tr.classList.add(hora > 13 ? "tarde" : "mañana");
|
|
||||||
if (minute == "00") {
|
|
||||||
const th = document.createElement("th");
|
|
||||||
th.classList.add("text-center");
|
|
||||||
th.scope = "row";
|
|
||||||
th.rowSpan = 4;
|
|
||||||
th.innerText = `${hora}:00`;
|
|
||||||
th.style.verticalAlign = "middle";
|
|
||||||
tr.appendChild(th);
|
|
||||||
}
|
|
||||||
["lunes", "martes", "miércoles", "jueves", "viernes", "sábado"].forEach(día => {
|
|
||||||
const td = document.createElement("td");
|
|
||||||
td.id = `hora-${hora}:${minute}-${día}`;
|
|
||||||
tr.appendChild(td);
|
|
||||||
});
|
|
||||||
const tbody = document.querySelector("tbody#horario");
|
|
||||||
if (!(tbody instanceof HTMLTableSectionElement)) {
|
|
||||||
throw new Error("No se ha encontrado el tbody");
|
|
||||||
}
|
|
||||||
tbody.appendChild(tr);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
const empty_table = table.cloneNode(true);
|
|
||||||
document.querySelectorAll('.hidden').forEach((element) => {
|
|
||||||
element.style.display = "none";
|
|
||||||
});
|
|
||||||
// hide the table
|
|
||||||
table.style.display = "none";
|
|
||||||
function moveHorario(id, día, hora) {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("id", id);
|
|
||||||
formData.append("hora", hora);
|
|
||||||
formData.append("día", día);
|
|
||||||
fetch("action/action_horario_update.php", {
|
|
||||||
method: "POST",
|
|
||||||
body: formData
|
|
||||||
}).then(res => res.json()).then(response => {
|
|
||||||
if (response.status == "success") {
|
|
||||||
triggerMessage("Horario movido", "Éxito", "success");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
triggerMessage(response.message, "Error");
|
|
||||||
}
|
|
||||||
}).then(() => {
|
|
||||||
renderHorario();
|
|
||||||
}).catch(err => {
|
|
||||||
triggerMessage(err, "Error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function renderHorario() {
|
|
||||||
if (horarios.length == 0) {
|
|
||||||
triggerMessage("Este profesor hay horarios para mostrar", "Error", "info");
|
|
||||||
table.style.display = "none";
|
|
||||||
document.querySelectorAll('.hidden').forEach((element) => element.style.display = "none");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// show the table
|
|
||||||
table.style.display = "table";
|
|
||||||
document.querySelectorAll('.hidden').forEach((element) => element.style.display = "block");
|
|
||||||
// clear the table
|
|
||||||
table.innerHTML = empty_table.outerHTML;
|
|
||||||
function conflicts(horario1, horario2) {
|
|
||||||
const { hora: hora_inicio1, hora_final: hora_final1, dia: dia1 } = horario1;
|
|
||||||
const { hora: hora_inicio2, hora_final: hora_final2, dia: dia2 } = horario2;
|
|
||||||
if (dia1 !== dia2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const compareInicios = compareHours(hora_inicio1, hora_inicio2);
|
|
||||||
const compareFinales = compareHours(hora_final1, hora_final2);
|
|
||||||
if (compareInicios >= 0 && compareInicios <= compareFinales ||
|
|
||||||
compareFinales >= 0 && compareFinales <= -compareInicios) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// remove the next 5 cells
|
|
||||||
function removeNextCells(horas, minutos, dia, cells = 5) {
|
|
||||||
for (let i = 1; i <= cells; i++) {
|
|
||||||
const minute = minutos + i * 15;
|
|
||||||
const nextMinute = (minute % 60).toString().padStart(2, "0");
|
|
||||||
const nextHour = horas + Math.floor(minute / 60);
|
|
||||||
const cellId = `hora-${nextHour}:${nextMinute}-${dia}`;
|
|
||||||
const cellElement = document.getElementById(cellId);
|
|
||||||
if (cellElement) {
|
|
||||||
cellElement.remove();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(`No se ha encontrado la celda ${cellId}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function newBlock(horario, edit = false) {
|
|
||||||
function move(horario, cells = 5) {
|
|
||||||
const [horas, minutos] = horario.hora.split(":").map(Number);
|
|
||||||
const cell = document.getElementById(`hora-${horas}:${minutos.toString().padStart(2, "0")}-${horario.dia}`);
|
|
||||||
const { top, left } = cell.getBoundingClientRect();
|
|
||||||
const block = document.getElementById(`block-${horario.id}`);
|
|
||||||
block.style.top = `${top}px`;
|
|
||||||
block.style.left = `${left}px`;
|
|
||||||
removeNextCells(horas, minutos, horario.dia, cells);
|
|
||||||
}
|
|
||||||
const [horas, minutos] = horario.hora.split(":").map(x => parseInt(x));
|
|
||||||
const hora = `${horas}:${minutos.toString().padStart(2, "0")}`;
|
|
||||||
horario.hora = hora;
|
|
||||||
const cell = document.getElementById(`hora-${horario.hora}-${horario.dia}`);
|
|
||||||
if (!cell)
|
|
||||||
return;
|
|
||||||
cell.dataset.ids = `${horario.id}`;
|
|
||||||
const float_menu = edit ?
|
|
||||||
`<div class="menu-flotante p-2" style="opacity: .7;">
|
|
||||||
<a class="mx-2" href="#" data-toggle="modal" data-target="#modal-editar">
|
|
||||||
<i class="ing-editar ing"></i>
|
|
||||||
</a>
|
|
||||||
<a class="mx-2" href="#" data-toggle="modal" data-target="#modal-borrar">
|
|
||||||
<i class="ing-basura ing"></i>
|
|
||||||
</a>
|
|
||||||
</div>`
|
|
||||||
: '';
|
|
||||||
cell.innerHTML =
|
|
||||||
`<div style="overflow-y: auto; overflow-x: hidden; height: 100%;" id="block-${horario.id}" class="position-absolute w-100 h-100">
|
|
||||||
<small class="text-gray">${horario.hora}</small>
|
|
||||||
<b class="title">${horario.materia}</b> <br>
|
|
||||||
<br><span>Salón: </span>${horario.salon} <br>
|
|
||||||
<small class="my-2">
|
|
||||||
${horario.profesores.map((profesor) => ` <span class="ing ing-formacion mx-1"></span>${profesor.grado ?? ''} ${profesor.profesor}`).join("<br>")}
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
${float_menu}`;
|
|
||||||
cell.classList.add("bloque-clase", "position-relative");
|
|
||||||
cell.rowSpan = horario.bloques;
|
|
||||||
// draggable
|
|
||||||
cell.draggable = write;
|
|
||||||
if (horario.bloques > 0) {
|
|
||||||
removeNextCells(horas, minutos, horario.dia, horario.bloques - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function newConflictBlock(horarios, edit = false) {
|
|
||||||
const first_horario = horarios[0];
|
|
||||||
const [horas, minutos] = first_horario.hora.split(":").map(x => parseInt(x));
|
|
||||||
const hora = `${horas}:${minutos.toString().padStart(2, "0")}`;
|
|
||||||
const ids = horarios.map(horario => horario.id);
|
|
||||||
const cell = document.getElementById(`hora-${hora}-${first_horario.dia}`);
|
|
||||||
if (cell == null) {
|
|
||||||
console.error(`Error: No se encontró la celda: hora-${hora}-${first_horario.dia}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cell.dataset.ids = ids.join(",");
|
|
||||||
// replace the content of the cell
|
|
||||||
cell.innerHTML = `
|
|
||||||
<small class='text-danger'>
|
|
||||||
${hora}
|
|
||||||
</small>
|
|
||||||
<div class="d-flex justify-content-center align-items-center mt-4">
|
|
||||||
<div class="d-flex flex-column justify-content-center align-items-center">
|
|
||||||
<span class="ing ing-importante text-danger" style="font-size: 2rem;"></span>
|
|
||||||
<b class='text-danger'>
|
|
||||||
Empalme de ${ids.length} horarios
|
|
||||||
</b>
|
|
||||||
<hr>
|
|
||||||
<i class="text-danger">Ver horarios …</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
// Add classes and attributes
|
|
||||||
cell.classList.add("conflict", "bloque-clase");
|
|
||||||
cell.setAttribute("role", "button");
|
|
||||||
// Add event listener for the cell
|
|
||||||
cell.addEventListener("click", () => {
|
|
||||||
$("#modal-choose").modal("show");
|
|
||||||
const ids = cell.getAttribute("data-ids").split(",").map(x => parseInt(x));
|
|
||||||
const tbody = document.querySelector("#modal-choose tbody");
|
|
||||||
tbody.innerHTML = "";
|
|
||||||
horarios.filter(horario => ids.includes(horario.id)).sort((a, b) => compareHours(a.hora, b.hora)).forEach(horario => {
|
|
||||||
tbody.innerHTML += `
|
|
||||||
<tr data-ids="${horario.id}">
|
|
||||||
<td><small>${horario.hora.slice(0, -3)}-${horario.hora_final.slice(0, -3)}</small></td>
|
|
||||||
<td>${horario.materia}</td>
|
|
||||||
<td>
|
|
||||||
${horario.profesores.map(({ grado, profesor }) => `${grado ?? ''} ${profesor}`).join(", ")}
|
|
||||||
</td>
|
|
||||||
<td>${horario.salon}</td>
|
|
||||||
${edit ? `
|
|
||||||
<td class="text-center">
|
|
||||||
<button class="btn btn-sm btn-primary dismiss-editar" data-toggle="modal" data-target="#modal-editar">
|
|
||||||
<i class="ing-editar ing"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
<td class="text-center">
|
|
||||||
<button class="btn btn-sm btn-danger dismiss-editar" data-toggle="modal" data-target="#modal-borrar">
|
|
||||||
<i class="ing-basura ing"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
` : ""}
|
|
||||||
</tr>`;
|
|
||||||
});
|
|
||||||
document.querySelectorAll(".dismiss-editar").forEach(btn => {
|
|
||||||
btn.addEventListener("click", () => $("#modal-choose").modal("hide"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
function getDuration(hora_i, hora_f) {
|
|
||||||
const [horas_i, minutos_i] = hora_i.split(":").map(x => parseInt(x));
|
|
||||||
const [horas_f, minutos_f] = hora_f.split(":").map(x => parseInt(x));
|
|
||||||
const date_i = new Date(0, 0, 0, horas_i, minutos_i);
|
|
||||||
const date_f = new Date(0, 0, 0, horas_f, minutos_f);
|
|
||||||
const diffInMilliseconds = date_f.getTime() - date_i.getTime();
|
|
||||||
const diffInMinutes = diffInMilliseconds / (1000 * 60);
|
|
||||||
const diffIn15MinuteIntervals = diffInMinutes / 15;
|
|
||||||
return Math.floor(diffIn15MinuteIntervals);
|
|
||||||
}
|
|
||||||
const maxHoraFinal = horarios.reduce((max, horario) => {
|
|
||||||
const [horas, minutos] = horario.hora_final.split(":").map(x => parseInt(x));
|
|
||||||
const date = new Date(0, 0, 0, horas, minutos);
|
|
||||||
return date > max ? date : max;
|
|
||||||
}, new Date(0, 0, 0, 0, 0));
|
|
||||||
const horaFinalMax = new Date(0, 0, 0, maxHoraFinal.getHours(), maxHoraFinal.getMinutes());
|
|
||||||
const blocks = getDuration(first_horario.hora, `${horaFinalMax.getHours()}:${horaFinalMax.getMinutes()}`);
|
|
||||||
cell.setAttribute("rowSpan", blocks.toString());
|
|
||||||
removeNextCells(horas, minutos, first_horario.dia, blocks - 1);
|
|
||||||
}
|
|
||||||
const conflictBlocks = horarios.filter((horario, index, arrayHorario) => arrayHorario.filter((_, i) => i != index).some(horario2 => conflicts(horario, horario2)))
|
|
||||||
.sort((a, b) => compareHours(a.hora, b.hora));
|
|
||||||
const classes = horarios.filter(horario => !conflictBlocks.includes(horario));
|
|
||||||
const conflictBlocksPacked = []; // array of sets
|
|
||||||
conflictBlocks.forEach(horario => {
|
|
||||||
const setIndex = conflictBlocksPacked.findIndex(set => set.some(horario2 => conflicts(horario, horario2)));
|
|
||||||
if (setIndex === -1) {
|
|
||||||
conflictBlocksPacked.push([horario]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
conflictBlocksPacked[setIndex].push(horario);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
classes.forEach(horario => newBlock(horario, write));
|
|
||||||
conflictBlocksPacked.forEach(horarios => newConflictBlock(horarios, write));
|
|
||||||
// remove the elements that are not in the limits
|
|
||||||
let max_hour = Math.max(...horarios.map(horario => {
|
|
||||||
const lastMoment = moment(horario.hora, "HH:mm").add(horario.bloques * 15, "minutes");
|
|
||||||
const lastHour = moment(`${lastMoment.hours()}:00`, "HH:mm");
|
|
||||||
const hourInt = parseInt(lastMoment.format("HH"));
|
|
||||||
return lastMoment.isSame(lastHour) ? hourInt - 1 : hourInt;
|
|
||||||
}));
|
|
||||||
let min_hour = Math.min(...horarios.map(horario => parseInt(horario.hora.split(":")[0])));
|
|
||||||
document.querySelectorAll("tbody#horario tr").forEach(hora => {
|
|
||||||
const hora_id = parseInt(hora.id.split("-")[1].split(":")[0]);
|
|
||||||
(hora_id < min_hour || hora_id > max_hour) ? hora.remove() : null;
|
|
||||||
});
|
|
||||||
// if there is no sábado, remove the column
|
|
||||||
if (!horarios.some(horario => horario.dia == "sábado")) {
|
|
||||||
document.querySelectorAll("tbody#horario td").forEach(td => {
|
|
||||||
if (td.id.split("-")[2] == "sábado") {
|
|
||||||
td.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// remove the header (the last)
|
|
||||||
document.querySelector("#headers").lastElementChild.remove();
|
|
||||||
}
|
|
||||||
// adjust width
|
|
||||||
const ths = document.querySelectorAll("tr#headers th");
|
|
||||||
ths.forEach((th, key) => th.style.width = (key == 0) ? "5%" : `${95 / (ths.length - 1)}%`);
|
|
||||||
// search item animation
|
|
||||||
const menúFlontantes = document.querySelectorAll(".menu-flotante");
|
|
||||||
menúFlontantes.forEach((element) => {
|
|
||||||
element.classList.add("d-none");
|
|
||||||
element.parentElement.addEventListener("mouseover", () => element.classList.remove("d-none"));
|
|
||||||
element.parentElement.addEventListener("mouseout", (e) => element.classList.add("d-none"));
|
|
||||||
});
|
|
||||||
// droppables
|
|
||||||
// forall the .bloque-elements add the event listeners for drag and drop
|
|
||||||
document.querySelectorAll(".bloque-clase").forEach(element => {
|
|
||||||
function dragStart() {
|
|
||||||
this.classList.add("dragging");
|
|
||||||
}
|
|
||||||
function dragEnd() {
|
|
||||||
this.classList.remove("dragging");
|
|
||||||
}
|
|
||||||
element.addEventListener("dragstart", dragStart);
|
|
||||||
element.addEventListener("dragend", dragEnd);
|
|
||||||
});
|
|
||||||
// forall the cells that are not .bloque-clase add the event listeners for drag and drop
|
|
||||||
document.querySelectorAll("td:not(.bloque-clase)").forEach(element => {
|
|
||||||
function dragOver(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.classList.add("dragging-over");
|
|
||||||
}
|
|
||||||
function dragLeave() {
|
|
||||||
this.classList.remove("dragging-over");
|
|
||||||
}
|
|
||||||
function drop() {
|
|
||||||
this.classList.remove("dragging-over");
|
|
||||||
const dragging = document.querySelector(".dragging");
|
|
||||||
const id = dragging.getAttribute("data-ids");
|
|
||||||
const hora = this.id.split("-")[1];
|
|
||||||
const días = ["lunes", "martes", "miércoles", "jueves", "viernes", "sábado"];
|
|
||||||
let día = this.id.split("-")[2];
|
|
||||||
día = días.indexOf(día) + 1;
|
|
||||||
// rowspan
|
|
||||||
const bloques = parseInt(dragging.getAttribute("rowspan"));
|
|
||||||
const horaMoment = moment(hora, "HH:mm");
|
|
||||||
const horaFin = horaMoment.add(bloques * 15, "minutes");
|
|
||||||
const limit = moment('22:00', 'HH:mm');
|
|
||||||
if (horaFin.isAfter(limit)) {
|
|
||||||
triggerMessage("No se puede mover el bloque a esa hora", "Error");
|
|
||||||
// scroll to the top
|
|
||||||
window.scrollTo(0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// get the horario
|
|
||||||
// remove the horario
|
|
||||||
const bloque = document.querySelector(`.bloque-clase[data-ids="${id}"]`);
|
|
||||||
// remove all children
|
|
||||||
while (bloque.firstChild) {
|
|
||||||
bloque.removeChild(bloque.firstChild);
|
|
||||||
}
|
|
||||||
// prepend a loading child
|
|
||||||
const loading = `<div class="spinner-border" role="status" style="width: 3rem; height: 3rem;">
|
|
||||||
<span class="sr-only">Loading...</span>
|
|
||||||
</div>`;
|
|
||||||
bloque.insertAdjacentHTML("afterbegin", loading);
|
|
||||||
// add style vertical-align: middle
|
|
||||||
bloque.style.verticalAlign = "middle";
|
|
||||||
bloque.classList.add("text-center");
|
|
||||||
// remove draggable
|
|
||||||
bloque.removeAttribute("draggable");
|
|
||||||
moveHorario(id, día, hora);
|
|
||||||
}
|
|
||||||
element.addEventListener("dragover", dragOver);
|
|
||||||
element.addEventListener("dragleave", dragLeave);
|
|
||||||
element.addEventListener("drop", drop);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const form = document.getElementById('form');
|
|
||||||
if (!(form instanceof HTMLFormElement)) {
|
|
||||||
triggerMessage('No se ha encontrado el formulario', 'Error', 'danger');
|
|
||||||
throw new Error("No se ha encontrado el formulario");
|
|
||||||
}
|
|
||||||
form.querySelector('#clave_profesor').addEventListener('input', function (e) {
|
|
||||||
const input = form.querySelector('#clave_profesor');
|
|
||||||
const option = form.querySelector(`option[value="${input.value}"]`);
|
|
||||||
if (input.value == "") {
|
|
||||||
input.classList.remove("is-invalid", "is-valid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!option) {
|
|
||||||
input.classList.remove("is-valid");
|
|
||||||
input.classList.add("is-invalid");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const profesor_id = form.querySelector('#profesor_id');
|
|
||||||
profesor_id.value = option.dataset.id;
|
|
||||||
input.classList.remove("is-invalid");
|
|
||||||
input.classList.add("is-valid");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
form.addEventListener('submit', async function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const input = form.querySelector('#clave_profesor');
|
|
||||||
if (input.classList.contains("is-invalid")) {
|
|
||||||
triggerMessage('El profesor no se encuentra registrado', 'Error', 'danger');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const formData = new FormData(form);
|
|
||||||
try {
|
|
||||||
const buttons = document.querySelectorAll("button");
|
|
||||||
buttons.forEach(button => {
|
|
||||||
button.disabled = true;
|
|
||||||
button.classList.add("disabled");
|
|
||||||
});
|
|
||||||
const response = await fetch('action/action_horario_profesor.php', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData,
|
|
||||||
});
|
|
||||||
const data = await response.json();
|
|
||||||
buttons.forEach(button => {
|
|
||||||
button.disabled = false;
|
|
||||||
button.classList.remove("disabled");
|
|
||||||
});
|
|
||||||
if (data.status == 'success') {
|
|
||||||
horarios = data.data;
|
|
||||||
renderHorario();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
triggerMessage(data.message, 'Error en la consulta', 'warning');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
triggerMessage('Fallo al consutar los datos ', 'Error', 'danger');
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const input = form.querySelector('#clave_profesor');
|
|
||||||
const option = form.querySelector(`option[value="${input.value}"]`);
|
|
||||||
@@ -10,7 +10,7 @@ if (!isset($_SESSION['user']))
|
|||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && in_array($user->acceso, ['r', 'n'])) {
|
if (in_array($user->acceso, ['r', 'n'])) {
|
||||||
// die($access);
|
// die($access);
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ if (!isset($_SESSION['user'])) {
|
|||||||
} else
|
} else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && $user->acceso == 'n') {
|
if ($user->acceso == null) {
|
||||||
// die($access);
|
// die($access);
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,228 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* Selects con datalist
|
|
||||||
*/
|
|
||||||
var click_in_process = false;
|
|
||||||
/*$('.datalist-text ul li').mousedown(function() {
|
|
||||||
click_in_process = true;
|
|
||||||
});
|
|
||||||
$('.datalist-text ul li').mouseup(function() {
|
|
||||||
click_in_process = false;
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
elementRoot.find('.datalist-input').focus();
|
|
||||||
});*/
|
|
||||||
|
|
||||||
$('.datalist-text .datalist-input').on('focusin', function () {
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
elementRoot.find(".icono").show();
|
|
||||||
elementRoot.find("ul").show();
|
|
||||||
elementRoot.find(".datalist-input").trigger("keyup");
|
|
||||||
});
|
|
||||||
|
|
||||||
//$('.datalist-input').click(function(){
|
|
||||||
$(document).on('click', '.datalist-input', function () {
|
|
||||||
var elementRoot = $(this).parent();
|
|
||||||
limpiaInput({ "data": { "padre": elementRoot } });
|
|
||||||
|
|
||||||
if (!elementRoot.hasClass("disabled")) {
|
|
||||||
elementRoot.find('ul').show();
|
|
||||||
elementRoot.find('.datalist-input').focus();
|
|
||||||
elementRoot.find('ul').show();
|
|
||||||
elementRoot.find('.icono').removeClass('ing-buscar').addClass('ing-cancelar iconoAzul pointer');
|
|
||||||
elementRoot.find('.icono').on('click', { "padre": elementRoot }, limpiaInput);
|
|
||||||
elementRoot.find('.icono').on('click', { "padre": elementRoot }, ocultaList);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function ocultaList(e) {
|
|
||||||
(e.data.padre).find('.icono').removeClass('ing-cancelar iconoAzul pointer').addClass('ing-buscar');
|
|
||||||
(e.data.padre).find('ul').hide();
|
|
||||||
/*$('.datalist .icono').removeClass('ing-cancelar iconoAzul pointer').addClass('ing-buscar');
|
|
||||||
$('.datalist ul').hide();*/
|
|
||||||
}
|
|
||||||
|
|
||||||
//usar class="selected" para marcar seleccioando por default
|
|
||||||
$(function () {
|
|
||||||
$.each($(".datalist").find('ul li:not(.not-selectable)'), function () {
|
|
||||||
if ($(this).hasClass("selected")) {
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
elementRoot.find('.datalist-input').text($(this).html().replace(/[\t\n]+/g, ' ').trim());
|
|
||||||
var cid = $(this).data('id');
|
|
||||||
elementRoot.find("input[type=hidden]").val(cid);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', '.datalist-select > ul li:not(.not-selectable)', function () {
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
elementRoot.find('.datalist-input').text($(this).html().replace(/[\t\n]+/g, ' ').trim());
|
|
||||||
//$(this).parent('ul').siblings('input[type="text"]').blur();
|
|
||||||
ocultaList({ "data": { "padre": elementRoot } });
|
|
||||||
var cid = $(this).data('id');
|
|
||||||
elementRoot.find("input[type=hidden]").val(cid);
|
|
||||||
elementRoot.find("li").removeClass("selected");
|
|
||||||
$(this).addClass("selected");
|
|
||||||
elementRoot.removeClass("datalist-invalid");
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$('.modal').on('hide.bs.modal', function (e) {
|
|
||||||
$('.datalist .icono').removeClass('ing-cancelar iconoAzul pointer').addClass('ing-buscar');
|
|
||||||
$('.datalist ul').hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
function setDatalist(selector, value = -1) {
|
|
||||||
var elementRoot = $(selector).parents('.datalist');
|
|
||||||
$.each(elementRoot.find('ul li:not(.not-selectable)'), function () {
|
|
||||||
if ($(this).data("id") == value) {
|
|
||||||
elementRoot.find('.datalist-input').text($(this).html().replace(/[\t\n]+/g, ' ').trim());
|
|
||||||
$(selector).val(value);
|
|
||||||
elementRoot.find("li").removeClass("selected");
|
|
||||||
$(this).addClass("selected");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDatalistFirst(selector) {
|
|
||||||
var index = 1;
|
|
||||||
var elementRoot = $(selector).parents('.datalist');
|
|
||||||
var num = elementRoot.find('ul li:not(.not-selectable)').length;
|
|
||||||
if (index <= num) {
|
|
||||||
while (elementRoot.find('ul li:nth-child(' + index + ')').hasClass("not-selectable") && index <= num) {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
var element = elementRoot.find('ul li:nth-child(' + index + ')');
|
|
||||||
elementRoot.find('.datalist-input').text(element.html().replace(/[\t\n]+/g, ' ').trim());
|
|
||||||
$(selector).val(element.data("id"));
|
|
||||||
elementRoot.find("li").removeClass("selected");
|
|
||||||
element.addClass("selected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function disableDatalist(selector, disabled = true) {
|
|
||||||
var elementRoot = $(selector).parents('.datalist');
|
|
||||||
if (disabled) {
|
|
||||||
elementRoot.addClass("disabled");
|
|
||||||
ocultaList({ "data": { "padre": elementRoot } });
|
|
||||||
} else
|
|
||||||
elementRoot.removeClass("disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function invalidDatalist(selector, invalid = true) {
|
|
||||||
var elementRoot = $(selector).parents('.datalist');
|
|
||||||
if (invalid) {
|
|
||||||
elementRoot.addClass("datalist-invalid");
|
|
||||||
} else
|
|
||||||
elementRoot.removeClass("datalist-invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
function buscaDatalist(selector, valor) {
|
|
||||||
selector.find('ul li').each(function () {
|
|
||||||
var elem = $(this);
|
|
||||||
if ($(this).parent().is('li'))
|
|
||||||
elem = $(this).parent();
|
|
||||||
if (!$(this).html().toUpperCase().includes(valor.toUpperCase())) {
|
|
||||||
$(elem).hide();
|
|
||||||
selector.find('.datalist-input').val("");
|
|
||||||
selector.find("input[type=hidden]").val("");
|
|
||||||
} else
|
|
||||||
$(elem).show();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function getDatalistText(selector, valor) {
|
|
||||||
var elementRoot = $(selector).parents('.datalist');
|
|
||||||
var text = "";
|
|
||||||
$.each(elementRoot.find('ul li:not(.not-selectable)'), function () {
|
|
||||||
if ($(this).data("id") == valor) {
|
|
||||||
text = $(this).html();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
//---
|
|
||||||
$('.datalist-text .datalist-input').keyup(function () {
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
var input = $(this);
|
|
||||||
elementRoot.find('ul li').each(function () {
|
|
||||||
var elem = $(this);
|
|
||||||
if ($(this).parent().is('li'))
|
|
||||||
elem = $(this).parent();
|
|
||||||
if (!$(this).html().toUpperCase().includes(input.val().toUpperCase()))
|
|
||||||
$(elem).hide();
|
|
||||||
else
|
|
||||||
$(elem).show();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
$('.datalist-text input').blur(function() {
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
console.log("Click? "+click_in_process);
|
|
||||||
if(!click_in_process) {
|
|
||||||
buscaDatalist(elementRoot, elementRoot.find('.datalist-input').val());
|
|
||||||
|
|
||||||
elementRoot.find('.icono').removeClass('ing-cancelar iconoAzul pointer').addClass('ing-buscar');
|
|
||||||
elementRoot.find('ul').children('li').show();
|
|
||||||
elementRoot.find('ul').hide();
|
|
||||||
}
|
|
||||||
click_in_process = false;
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
$('.datalist-text > ul li:not(.not-selectable)').click(function () {
|
|
||||||
console.log("Li click!" + $(this).html());
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
elementRoot.find('.datalist-input').val($(this).html().replace(/[\t\n]+/g, ' ').trim());
|
|
||||||
|
|
||||||
//$(this).parent('ul').siblings('input[type="text"]').blur();
|
|
||||||
|
|
||||||
var cid = $(this).data('id');
|
|
||||||
elementRoot.find("input[type=hidden]").val(cid);
|
|
||||||
elementRoot.find("li").removeClass("selected");
|
|
||||||
$(this).addClass("selected");
|
|
||||||
click_in_process = true;
|
|
||||||
//elementRoot.find('.datalist-input').blur();
|
|
||||||
ocultaList({ "data": { "padre": elementRoot } });
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.datalist-text .datalist-input').click(function () {
|
|
||||||
var elementRoot = $(this).parents('.datalist');
|
|
||||||
limpiaInput({ "data": { "padre": elementRoot } });
|
|
||||||
elementRoot.find('ul').show();
|
|
||||||
elementRoot.find('input').focus();
|
|
||||||
elementRoot.find('ul').show();
|
|
||||||
elementRoot.find('.icono').removeClass('ing-buscar').addClass('ing-cancelar iconoAzul pointer');
|
|
||||||
elementRoot.find('.icono').on('click', { "padre": elementRoot }, limpiaInput);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function limpiaInput(e) {
|
|
||||||
(e.data.padre).find('.datalist-input').val('');
|
|
||||||
(e.data.padre).find('.datalist-input').parent().children('ul').children('li').show();
|
|
||||||
(e.data.padre).find('li:first').focus();
|
|
||||||
(e.data.padre).find('.datalist-input').focus();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// function make required
|
|
||||||
function makeRequiredDatalist(selector, required = true) {
|
|
||||||
var elementRoot = $(selector).parents('.datalist');
|
|
||||||
if (required)
|
|
||||||
elementRoot.addClass("required");
|
|
||||||
else
|
|
||||||
elementRoot.removeClass("required");
|
|
||||||
}
|
|
||||||
|
|
||||||
// function validate
|
|
||||||
function validateDatalist(selector) {
|
|
||||||
var elementRoot = $(selector).parents('.datalist');
|
|
||||||
if (elementRoot.hasClass("required") && $(selector).val() == "") {
|
|
||||||
invalidDatalist(selector, true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
invalidDatalist(selector, false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { makeRequiredDatalist, validateDatalist, disableDatalist, invalidDatalist, getDatalistText, ocultaList, limpiaInput, buscaDatalist, setDatalist };
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
export function triggerMessage(message, header, color = "danger", selector = "message") {
|
|
||||||
const container = document.getElementById(selector);
|
|
||||||
container.innerHTML = '';
|
|
||||||
/* Template message_tmp */
|
|
||||||
var node = /* html */`
|
|
||||||
<article class="alert alert-${color} alert-dismissible fade show" role="alert" id="alert-color">
|
|
||||||
<h4 class="alert-heading"><span class="ing-${(color !== 'success') ? 'importante' : 'aceptar'}"></span> ${header}</h4>
|
|
||||||
<span id="message-alert">${message}</span>
|
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</article>
|
|
||||||
`
|
|
||||||
setTimeout(function () {
|
|
||||||
container.innerHTML = node;
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
|
|
||||||
/* setTimeout(function () {
|
|
||||||
container.innerHTML = '';
|
|
||||||
}, 5000); */
|
|
||||||
}
|
|
||||||
|
|
||||||
export function messageMissingInputs(required) {
|
|
||||||
var message = 'Faltan los siguientes campos: ';
|
|
||||||
required.forEach(function (item, index) {
|
|
||||||
let last = required.length - 1;
|
|
||||||
if (index == last)
|
|
||||||
message += item;
|
|
||||||
else if (index == last - 1)
|
|
||||||
message += item + ' y ';
|
|
||||||
else
|
|
||||||
message += item + ', ';
|
|
||||||
});
|
|
||||||
triggerMessage(message, 'Error', 'danger');
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Permisos');
|
$user->print_to_log('Permisos');
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ if (!isset($_SESSION['user'])) {
|
|||||||
} else
|
} else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && $user->acceso == 'n') {
|
if ($user->acceso == null) {
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
} else {
|
} else {
|
||||||
$user->print_to_log('Profesores');
|
$user->print_to_log('Profesores');
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user']))
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access('reporte_de_asistencias');
|
$user->access('reporte_de_asistencias');
|
||||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
if (in_array($user->acceso, ['n']))
|
||||||
die(header('Location: main.php?error=1'));
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
$user->print_to_log('Consultar asistencia');
|
$user->print_to_log('Consultar asistencia');
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ if (!isset($_SESSION['user']))
|
|||||||
|
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
if (in_array($user->acceso, ['n']))
|
||||||
die(header('Location: main.php?error=1'));
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
$user->print_to_log('Consultar horario');
|
$user->print_to_log('Consultar horario');
|
||||||
|
|||||||
767
reposiciones_autorizar.php
Normal file
767
reposiciones_autorizar.php
Normal file
@@ -0,0 +1,767 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'class/c_login.php';
|
||||||
|
if (!isset($_SESSION['user'])){
|
||||||
|
die(header('Location: index.php'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
|
$user->access();
|
||||||
|
//if (!$user->admin && in_array($user->acceso, ['n']))
|
||||||
|
//die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
|
$user->print_to_log('Reposiciones');
|
||||||
|
//$write = $user->admin || in_array($user->acceso, ['w']);
|
||||||
|
$write = true; //
|
||||||
|
|
||||||
|
function duracionMinutos($fechahora_i, $fechahora_f){
|
||||||
|
return round((strtotime($fechahora_f) - strtotime($fechahora_i)) / 60,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty($user->periodo)){
|
||||||
|
$en_fecha = $db->querySingle("SELECT ESTA_EN_PERIODO(NOW()::DATE, :periodo_id)", [':periodo_id' => $user->periodo])['esta_en_periodo'];
|
||||||
|
|
||||||
|
|
||||||
|
$profesores_rs = array();
|
||||||
|
$tab_inicial = 1;
|
||||||
|
if($user->jefe_carrera){
|
||||||
|
$carrera_rs = $db->query('SELECT * FROM fs_usuario_carrera(:usr, NULL)', [':usr'=>$user->user["id"]]);
|
||||||
|
foreach($carrera_rs as $carr){
|
||||||
|
$rs = $db->query('SELECT * FROM fs_profesor_carrera(:carr, :periodo)', [':carr' => $carr['carrera_id'], ':periodo' => $user->periodo]);
|
||||||
|
$profesores_rs = array_merge($profesores_rs, $rs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if($write){// $user->supervisor || $user->admin
|
||||||
|
$profesores_rs = $db->query('SELECT * FROM fs_profesor_carrera(NULL, :periodo)', [':periodo' => $user->periodo]);
|
||||||
|
$tab_inicial = 2;
|
||||||
|
}else{
|
||||||
|
die(header('Location: index.php'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$salones_rs = $db->query('SELECT * FROM salon_view WHERE tiene_salones IS true');
|
||||||
|
|
||||||
|
|
||||||
|
//Periodo
|
||||||
|
$periodo_rs = $db->querySingle('SELECT periodo_fecha_inicio, periodo_fecha_fin FROM periodo WHERE periodo_id = :periodo_id', [':periodo_id' => $user->periodo]);
|
||||||
|
$periodo_fin = $periodo_rs["periodo_fecha_fin"];
|
||||||
|
if(strtotime($periodo_rs["periodo_fecha_inicio"])>strtotime(date("Y-m-d")) )
|
||||||
|
$fecha_man = date("d/m/Y", strtotime($periodo_rs["periodo_fecha_inicio"]));
|
||||||
|
else{
|
||||||
|
$dias = 3;
|
||||||
|
if( intval(date("w")) >=3 && intval(date("w"))<=5 )//Mie a Vie
|
||||||
|
$dias+=3;
|
||||||
|
else if( intval(date("w")) ==6 )//Sab
|
||||||
|
$dias+=2;
|
||||||
|
else if( intval(date("w")) ==0 )//Do
|
||||||
|
$dias+=1;
|
||||||
|
|
||||||
|
$fecha_man = date("d/m/Y", strtotime("+".$dias." day"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fechas filtro
|
||||||
|
if(isset($_POST["fecha_inicial"]))
|
||||||
|
$fecha_ini = $_POST["fecha_inicial"];
|
||||||
|
else
|
||||||
|
$fecha_ini = date("d/m/Y", strtotime($periodo_rs["periodo_fecha_inicio"]));
|
||||||
|
|
||||||
|
if(isset($_POST["fecha_final"]))
|
||||||
|
$fecha_fin = $_POST["fecha_final"];
|
||||||
|
else
|
||||||
|
$fecha_fin = date("d/m/Y", strtotime($periodo_rs["periodo_fecha_fin"]));
|
||||||
|
|
||||||
|
|
||||||
|
//Reposiciones
|
||||||
|
$repEdo_rs = $db->query('SELECT * FROM fs_estado_reposicion' );
|
||||||
|
|
||||||
|
$repoParams = array();
|
||||||
|
$query = "";//carrera, prof
|
||||||
|
if($user->jefe_carrera){
|
||||||
|
$query .= ":jefe, ";
|
||||||
|
$repoParams[":jefe"] = $user->user["id"];
|
||||||
|
}else{
|
||||||
|
$query .= "NULL, ";
|
||||||
|
}
|
||||||
|
if((isset($_POST["prof"]) && is_numeric($_POST["prof"])) ){
|
||||||
|
$query .= ":prof,";
|
||||||
|
$repoParams[":prof"] = filter_input(INPUT_POST, "prof", FILTER_SANITIZE_NUMBER_INT);//limpia texto
|
||||||
|
}else{
|
||||||
|
$query .= "NULL,";
|
||||||
|
}
|
||||||
|
$query .= ":f_ini, :f_fin, :edo, ";
|
||||||
|
$repoParams[":f_ini"] = $fecha_ini;
|
||||||
|
$repoParams[":f_fin"] = $fecha_fin;
|
||||||
|
$repoParams[":edo"] = 1;//se sobreescribe
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Reposiciones autorizar | <?= $user->facultad['facultad'] ?? 'General' ?></title>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="content-type" content="text/plain; 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"; ?>
|
||||||
|
<link rel="stylesheet" href="css/jquery-ui.css">
|
||||||
|
<link rel="stylesheet" href="css/richtext.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="css/clockpicker.css">
|
||||||
|
<link rel="stylesheet" href="css/calendar.css">
|
||||||
|
<link rel="stylesheet" href="css/fa_all.css" type="text/css">
|
||||||
|
|
||||||
|
<script src="js/scrollables.js" defer></script>
|
||||||
|
<script>
|
||||||
|
const write = <?= $write ? 'true' : 'false' ?>;
|
||||||
|
</script>
|
||||||
|
<script src="js/moment.js" defer></script>
|
||||||
|
<style>
|
||||||
|
.wizard { height: 20px; width: 80%; background: #D0D0D0; }
|
||||||
|
.wizard.full { background: #D0D0D0; }
|
||||||
|
.wizard.active > div:first-child { background: #00A6CE; }
|
||||||
|
.wizard.active > div:last-child { width: 0px; height: 0px; border-style: solid; border-width: 10px 0 10px 6px; border-color: transparent transparent transparent #00a6ce; transform: rotate(0deg); }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<body style="display: block;">
|
||||||
|
<?php
|
||||||
|
include('include/constantes.php');
|
||||||
|
include("import/html_header.php");
|
||||||
|
html_header("Reposiciones de clase", "Sistema de gestión de checador");
|
||||||
|
?>
|
||||||
|
<?= "<!-- $user -->" ?>
|
||||||
|
<main class="container content marco content-margin" id="local-app">
|
||||||
|
|
||||||
|
<section id="message"></section>
|
||||||
|
<?php require('import/periodo.php') ?>
|
||||||
|
|
||||||
|
<?php if(!empty($user->periodo)){ ?>
|
||||||
|
<form id="asistencia" method="post" onsubmit="return validaFechas()">
|
||||||
|
<div class="form-box">
|
||||||
|
<input type="hidden" name="facultad" value="5">
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="filtro_inicial" class="col-4 col-form-label">Fecha inicial</label>
|
||||||
|
<div class="col-8 col-sm-4">
|
||||||
|
<input id="filtro_inicial" name="fecha_inicial" type="text" class="form-control date-picker-filtro" placeholder="dd/mm/aaaa" maxlength="10" required="required" readonly="" value="<?php echo $fecha_ini;?>">
|
||||||
|
<div class="invalid-feedback">No es una fecha válida.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="filtro_final" class="col-4 col-form-label">Fecha final</label>
|
||||||
|
<div class="col-8 col-sm-4">
|
||||||
|
<input id="filtro_final" name="fecha_final" type="text" class="form-control date-picker-filtro" placeholder="dd/mm/aaaa" maxlength="10" required="required" readonly="" value="<?php echo $fecha_fin;?>">
|
||||||
|
<div class="invalid-feedback">El rango de fechas no es válido.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="filtro_prof" class="col-4 col-form-label">Profesor</label>
|
||||||
|
<div class="col-8 col-sm-4">
|
||||||
|
<input list="lista_profesores" name="dlProfesor" id="dlProfesor" class="form-control" placeholder="Profesor">
|
||||||
|
<div class="valid-feedback">
|
||||||
|
Profesor encontrado
|
||||||
|
</div>
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
Profesor no encontrado
|
||||||
|
</div>
|
||||||
|
<datalist id="lista_profesores">
|
||||||
|
<?php
|
||||||
|
foreach ($profesores_rs as $profesor) {
|
||||||
|
extract($profesor);
|
||||||
|
?>
|
||||||
|
<option data-clave="<?= $profesor_clave ?>" data-profesor="<?= $profesor_nombre ?>" data-id="<?= $profesor_id; ?>" value="<?= "$profesor_clave | $profesor_nombre" ?>"></option>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</datalist>
|
||||||
|
<ul class="list-group" id="profesores"></ul>
|
||||||
|
<input type="hidden" id="editor_profesor" name="profesor" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row justify-content-center">
|
||||||
|
<button type="submit" class="btn btn-outline-primary mr-2" id="btn-buscar"><span class="ing-buscar ing-fw"></span> Buscar</button>
|
||||||
|
<button type="button" class="btn btn-outline-danger" onclick="window.location.href = window.location.href"><span class="ing-borrar ing-fw"></span> Limpiar</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<ul class="nav nav-tabs d-print-none mb-4" id="myTab" role="tablist">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" id="tab1-tab" data-toggle="tab" href="#tab1" role="tab" aria-controls="calendario" aria-selected="true">Nuevas reposiciones</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" id="tab2-tab" data-toggle="tab" href="#tab2" role="tab" aria-controls="lista" aria-selected="false">Aprobadas por jefe</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" id="tab3-tab" data-toggle="tab" href="#tab3" role="tab" aria-controls="lista" aria-selected="false">Autorizadas</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" id="tab4-tab" data-toggle="tab" href="#tab4" role="tab" aria-controls="lista" aria-selected="false">Rechazadas</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content" id="TabContent">
|
||||||
|
<?php
|
||||||
|
$i=1;
|
||||||
|
foreach($repEdo_rs as $redo){ ?>
|
||||||
|
<div class="tab-pane fade" id="tab<?php echo $i;?>" role="tabpanel" aria-labelledby="tab<?php echo $i;?>-tab">
|
||||||
|
<?php
|
||||||
|
$repoParams[":edo"]=$redo["estado_reposicion_id"];
|
||||||
|
$reposiciones_rs = $db->query('SELECT * FROM fs_reposicion(NULL, '.$query.'0, NULL) ', $repoParams );
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h4 class="mb-4" <?php echo "style='color:".$redo["estado_color"]."'>".$redo["estado_nombre"]; ?> </h4>
|
||||||
|
|
||||||
|
<table class="table table-sm table-striped table-white">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Estado</th>
|
||||||
|
<th>Tipo</th>
|
||||||
|
<th>Profesor/Materia</th>
|
||||||
|
<th style="width:160px">Fecha falta</th>
|
||||||
|
<th style="width:160px">Fecha reposición</th>
|
||||||
|
<th>Salón</th>
|
||||||
|
<?php if($write){ ?><th>Acciones</th><?php } ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
if(isset($reposiciones_rs)){
|
||||||
|
foreach($reposiciones_rs as $reposicion){
|
||||||
|
?>
|
||||||
|
<tr data-id="<?php echo $reposicion["reposicion_id"]; ?>" data-edo="<?php echo $reposicion["estado_reposicion_id"];?>" id="id<?php echo $reposicion["reposicion_id"]; ?>">
|
||||||
|
<td class="align-middle">
|
||||||
|
<?php if($reposicion["estado_reposicion_id"]<3){ ?>
|
||||||
|
<div class="wizard <?php if(intval($reposicion["estado_reposicion_id"])==2) echo "active";?> d-flex mx-auto">
|
||||||
|
<div class="w-50 h-100"></div>
|
||||||
|
<div class=""></div>
|
||||||
|
</div>
|
||||||
|
<?php } else if($reposicion["estado_reposicion_id"]==3){?>
|
||||||
|
<div class="text-success text-center pt-1">
|
||||||
|
<span class="ing-autorizar ing-lg"></span>
|
||||||
|
</div>
|
||||||
|
<?php } else {?>
|
||||||
|
<div class="text-danger text-center pt-1">
|
||||||
|
<span class="ing-negar ing-lg"></span>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<?php if($reposicion["es_reposicion"]) echo "Resposición"; else echo "Cambio"; ?>
|
||||||
|
</td>
|
||||||
|
<td><?php
|
||||||
|
echo $reposicion["profesor_clave"]." - ".$reposicion["profesor_nombre"];
|
||||||
|
?>
|
||||||
|
<br>
|
||||||
|
<small>
|
||||||
|
<?php echo $reposicion["materia_nombre"]; ?>
|
||||||
|
(<?php
|
||||||
|
echo $reposicion["horario_grupo"];
|
||||||
|
?>)
|
||||||
|
</small>
|
||||||
|
</td>
|
||||||
|
<td class="text-center align-middle text-nowrap"><?php
|
||||||
|
$fechaI = date("d/m/Y", strtotime($reposicion["fecha_clase"]));
|
||||||
|
echo $fechaI."<br>".substr($reposicion["horario_hora"],0, 5);
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<td class="text-center align-middle text-nowrap"><?php
|
||||||
|
$fechaF = date("d/m/Y", strtotime($reposicion["fecha_nueva"]));
|
||||||
|
echo $fechaF."<br>".substr($reposicion["hora_nueva"],0, 5)." a ".substr($reposicion["hora_nueva_fin"],0, 5);
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<td class="text-center align-middle"><?php
|
||||||
|
if($reposicion["salon_id"] != ""){
|
||||||
|
echo $reposicion["salon_id"];
|
||||||
|
}else
|
||||||
|
echo "Pendiente";
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<?php if($write){ ?>
|
||||||
|
<td class="text-center align-middle icono-acciones text-nowrap">
|
||||||
|
<?php if (duracionMinutos($reposicion["fecha_nueva"], date("Y-m-d H:i:00")) < 0){ ?>
|
||||||
|
<?php //no se cumple la fecha de la reposicion, es jefe de carrera
|
||||||
|
if(($user->jefe_carrera || $user->admin) && $reposicion["estado_reposicion_id"] == 1){?>
|
||||||
|
<a href="#" data-toggle="modal" data-target="#modal_aprobar" data-tipo="2" title="Aprobar"><?php echo $ICO["ver"];?></a>
|
||||||
|
<?php } //no se cumple la fecha de la reposicion, no es jefe de carrera
|
||||||
|
else if((!$user->jefe_carrera || $user->admin) && $reposicion["estado_reposicion_id"] >= 2){?>
|
||||||
|
<a href="#" data-toggle="modal" data-target="#modal_aprobar" data-tipo="3" title="Autorizar" ><?php echo $ICO["ver"];?></a>
|
||||||
|
<?php } else { ?>
|
||||||
|
<a href="#" data-toggle="modal" data-target="#modal_aprobar" data-tipo="1" title="Aprobar"><?php echo $ICO["ver"];?></a>
|
||||||
|
<?php } ?>
|
||||||
|
<?php
|
||||||
|
}else{ //fecha ya pasó?>
|
||||||
|
<a href="#" data-toggle="modal" data-target="#modal_aprobar" data-tipo="1" title="Ver detalle"><span class="text-danger"><?php echo $ICO["ver"];?></span></a>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if($reposicion["estado_reposicion_id"]<4){
|
||||||
|
if(
|
||||||
|
(($user->jefe_carrera || $user->admin) && $reposicion["estado_reposicion_id"] <= 2)
|
||||||
|
|| ((!$user->jefe_carrera || $user->admin) && $reposicion["estado_reposicion_id"] >= 2 )){
|
||||||
|
?>
|
||||||
|
<a href="#" data-toggle="modal" data-target="#modal_confirm" title="Cancelar"><span class="text-danger"><?php echo $ICO["cancelar"];?></span></a>
|
||||||
|
<?php }
|
||||||
|
} //estado
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<?php }//edición ?>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}//foreach
|
||||||
|
}//if ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
$i++;
|
||||||
|
} ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Modal -->
|
||||||
|
<div class="modal fade" id="modal_aprobar" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="col-12 modal-title text-center"><span id="modalLabel">Aprobar Reposición</span>
|
||||||
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button></h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="./action/reposicion_autoriza.php" method="post" id="formaModal">
|
||||||
|
<input type="hidden" name="id" id="id">
|
||||||
|
<input type="hidden" name="edo" id="edo" value="">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Profesor</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-prof"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Materia</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-mat"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Tipo</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-tipo"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Fecha de falta</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-falta"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Fecha de reposición</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-fecha"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Alumnos aproximados</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-alumnos"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Tipo de aula</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-aula"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="salon-ver">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Salón</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<p class="rep-salon"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" id="salon-editar" style="display: none;">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Salón *</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input list="lista_salones" name="dlSalon" id="dlSalon" class="form-control" placeholder="Salón">
|
||||||
|
<div class="valid-feedback">
|
||||||
|
Salón encontrado
|
||||||
|
</div>
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
Salón no encontrado
|
||||||
|
</div>
|
||||||
|
<datalist id="lista_salones">
|
||||||
|
<?php
|
||||||
|
foreach ($salones_rs as $salon) {
|
||||||
|
extract($salon);
|
||||||
|
?>
|
||||||
|
<option data-id="<?= $salon_id ?>" data-nombre="<?= $salon ?>" value="<?= $salon ?>"></option>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</datalist>
|
||||||
|
<ul class="list-group" id="salones"></ul>
|
||||||
|
<input type="hidden" id="salon" name="salon" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row mt-4">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Comentarios</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 bg-light">
|
||||||
|
<p class="rep-comentarios"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
|
||||||
|
<p class="aprobar-block">Una vez realizada la acción no se puede deshacer.</p>
|
||||||
|
<p>
|
||||||
|
<button type="button" class="btn btn-primary btn-enviar aprobar-block" id="submitBtn" data-edo="<?php echo $edo_new; ?>" ><?php echo $ICO["aceptar"];?> Aprobar</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal" aria-label="Close">Cerrar</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modal_confirm" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<p class="font-weight-bold">¿Estás seguro de que quieres declinar la reposición?</p>
|
||||||
|
<p>Esta acción no se puede deshacer.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="./action/reposicion_autoriza.php" method="post">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 col-sm-4 barra-right text-right">
|
||||||
|
<p class="font-weight-bold">Motivo</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 col-sm-8">
|
||||||
|
<textarea name="motivo" id="motivo" rows="3" class="form-control"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 mt-4 text-center">
|
||||||
|
<input type="hidden" id="id_borrar" name="id" value="">
|
||||||
|
<input type="hidden" name="edo" value="4">
|
||||||
|
<button type="submit" class="btn btn-outline-primary btn-borrar"><?php echo $ICO["aceptar"];?> Declinar</button>
|
||||||
|
<button type="button" class="btn btn-outline-danger" data-dismiss="modal" aria-label="Close"><?php echo $ICO["cancelar"];?> Cerrar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/bootstrap/popper.min.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="js/datepicker-es.js"></script>
|
||||||
|
<script src="js/messages.js"></script>
|
||||||
|
<?php
|
||||||
|
//--Manejo de errores y mensajes de exito
|
||||||
|
if(isset($_GET["error"]) && is_numeric($_GET["error"])){
|
||||||
|
switch ($_GET["error"]){
|
||||||
|
case 0: $errorDesc = "No se reciberon los datos de la reposición."; break;
|
||||||
|
case 1: $errorDesc = "Ocurrió un error al insertar los datos de la reposición/cambio."; break;
|
||||||
|
case 2: $errorDesc = "Ocurrió un error al actualizar los datos de la reposición/cambio."; break;
|
||||||
|
case 3: $errorDesc = "No tienes permisos para realizar esa acción."; break;
|
||||||
|
case 4: $errorDesc = "Ocurrió un error al cargar los datos de la reposición/cambio."; break;
|
||||||
|
case 6: $errorDesc = "La reposición/cambio que buscas no existe. Consulta la lista de reopsiciones disponibles en esta sección."; break;
|
||||||
|
case 7: $errorDesc = "La reposición/cambio se empalma con el horario del grupo y no se puede guardar."; break;
|
||||||
|
case 8: $errorDesc = "El salón de la reposición está siendo utilizado ese día a esa hora y no se puede guardar."; break;
|
||||||
|
case 9: $errorDesc = "El profesor está asigndo a otra reposición/cambio el mismo día a la misma hora y no se puede guardar."; break;
|
||||||
|
case 10: $errorDesc = "El profesor está asigndo a una materia el mismo día a la misma hora y no se puede guardar."; break;
|
||||||
|
case 11: $errorDesc = "No hay clases asignadas para esa materia y grupo en la fecha de falta."; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isset($_GET["ok"]) && is_numeric($_GET["ok"])){
|
||||||
|
switch ($_GET["ok"]){
|
||||||
|
case 0: $successDesc = "La reposición se guardó correctamente."; break;
|
||||||
|
case 1: $successDesc = "La reposición se actualizó correctamente."; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require_once 'js/messages.php';
|
||||||
|
?>
|
||||||
|
<script>
|
||||||
|
<?php if(isset($errorDesc)){ ?>
|
||||||
|
triggerMessage("<?php echo $errorDesc;?>", "Error");
|
||||||
|
<?php } else if(isset($successDesc)){ ?>
|
||||||
|
triggerMessage("<?php echo $successDesc;?>", "Éxito", "success");
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
var _periodo_fecha_inicial = "<?php echo date("d/m/Y", strtotime($periodo_rs["periodo_fecha_inicio"])); ?>";
|
||||||
|
var _periodo_fecha_final = "<?php echo date("d/m/Y", strtotime($periodo_rs["periodo_fecha_fin"])); ?>";
|
||||||
|
var datepickerOptions = { dateFormat: "dd/mm/yy", minDate:_periodo_fecha_inicial, maxDate:_periodo_fecha_final };
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
$(".date-picker-filtro" ).datepicker(datepickerOptions);
|
||||||
|
$(".date-picker-filtro" ).datepicker( $.datepicker.regional[ "es" ] );
|
||||||
|
$('#tab<?php echo $tab_inicial;?>-tab').tab('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
function valida(){
|
||||||
|
<?php
|
||||||
|
if(!$user->jefe_carrera || $user->admin){ ?>
|
||||||
|
$("#salon").removeClass("is-invalid");
|
||||||
|
if($("#salon").val() === undefined || $("#salon").val() == 0 || $("#salon").val() == ''){
|
||||||
|
$("#salon").addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
<?php } ?>
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
$('#modal_confirm').on('show.bs.modal', function (event) {
|
||||||
|
var button = $(event.relatedTarget); // Button that triggered the modal
|
||||||
|
var id = button.parents("tr").data("id");
|
||||||
|
$("#id_borrar").val(id);
|
||||||
|
$("#motivo").val("")
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modal_aprobar').on('show.bs.modal', function (event) {
|
||||||
|
var button = $(event.relatedTarget); // Button that triggered the modal
|
||||||
|
//console.log(button.data("tipo"));
|
||||||
|
var id = button.parents("tr").data("id");
|
||||||
|
var edo = button.data('tipo');
|
||||||
|
|
||||||
|
$("#edo").val(edo);
|
||||||
|
$("#id").val(id);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: './action/reposicion_select.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { id: id},
|
||||||
|
success: function(result) {
|
||||||
|
if(result["error"]!= "" && result["error"] !== undefined){
|
||||||
|
triggerMessage(result["error"], "Error");
|
||||||
|
$('#modal_aprobar').modal("hide");
|
||||||
|
}else{
|
||||||
|
|
||||||
|
$("#modal_aprobar .rep-prof").text(result["profesor_nombre"]);
|
||||||
|
$("#modal_aprobar .rep-mat").text(result["materia_desc"]+" ["+result["grupo"]+"]" );
|
||||||
|
if(result["tipo"])
|
||||||
|
$("#modal_aprobar .rep-tipo").text("Reposición");
|
||||||
|
else
|
||||||
|
$("#modal_aprobar .rep-tipo").text("Cambio");
|
||||||
|
$("#modal_aprobar .rep-aula").text(result["aula_desc"])
|
||||||
|
$("#modal_aprobar .rep-aula").data("aula",result["aula"]);
|
||||||
|
$("#modal_aprobar .rep-falta").text(result["fecha_clase"]);
|
||||||
|
$("#modal_aprobar .rep-fecha").text(result["fecha_nueva"]+" de "+result["hora_ini"]+":"+result["min_ini"]+" a "+result["hora_fin"]+":"+result["min_fin"]);
|
||||||
|
if(result["salon"] =="" || result["salon"] === undefined){
|
||||||
|
$('#salon').prop("selectedIndex", 0);
|
||||||
|
}else{
|
||||||
|
$('#salon').val(result["salon"]);
|
||||||
|
}
|
||||||
|
$("#modal_aprobar .rep-salon").text(result["salon_desc"]);
|
||||||
|
$("#modal_aprobar .rep-comentarios").text(result["comentario"]);
|
||||||
|
$('#modal_aprobar .rep-alumnos').text(result["alumnos"]);
|
||||||
|
|
||||||
|
if(button.data("tipo") == 1){//ver
|
||||||
|
$("#modalLabel").text("Detalle de reposición");
|
||||||
|
$(".aprobar-block").hide();
|
||||||
|
$("#salon-ver").show();
|
||||||
|
$("#salon-editar").hide();
|
||||||
|
|
||||||
|
}else{
|
||||||
|
if(parseInt($("#modal_aprobar .rep-aula").data("aula")) == 1){//ver
|
||||||
|
$("#modalLabel").text("Detalle de reposición");
|
||||||
|
$(".aprobar-block").hide();
|
||||||
|
$("#salon-ver").show();
|
||||||
|
$("#salon-editar").hide();
|
||||||
|
}else{
|
||||||
|
$("#modalLabel").text("Aprobar reposición");
|
||||||
|
$(".aprobar-block").show();
|
||||||
|
if(button.data("tipo") == 3){//aprobar (con salón)
|
||||||
|
$("#salon-ver").hide();
|
||||||
|
$("#salon-editar").show();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result["aula_supervisor"]){//Solo supervisor
|
||||||
|
<?php if($user->supervisor){ ?>
|
||||||
|
$("#salon-editar").attr("disabled", false);
|
||||||
|
<?php }else{?>
|
||||||
|
$("#salon-editar").attr("disabled", true);
|
||||||
|
<?php } ?>
|
||||||
|
}else{// Facultad
|
||||||
|
<?php if(!$user->supervisor){ ?>
|
||||||
|
$("#salon-editar").attr("disabled", false);
|
||||||
|
<?php }else{?>
|
||||||
|
$("#salon-editar").attr("disabled", true);
|
||||||
|
<?php } ?>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown ){
|
||||||
|
triggerMessage(errorThrown, "Error");
|
||||||
|
}
|
||||||
|
});//ajax
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
$(".btn-borrar").click(function(){
|
||||||
|
var cid = $("#id_borrar").val();
|
||||||
|
$.ajax({
|
||||||
|
url: './action/reposicion_autoriza.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { id: cid, edo: 4},
|
||||||
|
success: function(result) {
|
||||||
|
if(result["error"]!= "" && result["error"] !== undefined){
|
||||||
|
$("#errorBox").collapse('show');
|
||||||
|
$("#errorBox_text").html(result["error"]);
|
||||||
|
}else{
|
||||||
|
$("#successBox").collapse('show');
|
||||||
|
$("#successBox_text").html(result["ok"]);
|
||||||
|
$("#id"+cid).remove();
|
||||||
|
}
|
||||||
|
$('#messageBox')[0].scrollIntoView({ block: "end" });
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown ){
|
||||||
|
$("#errorBox").collapse('show');
|
||||||
|
$("#errorBox_text").html(errorThrown);
|
||||||
|
$('#messageBox')[0].scrollIntoView({ block: "end" });
|
||||||
|
}
|
||||||
|
});//ajax
|
||||||
|
$('#modal_confirm').modal("hide");
|
||||||
|
});*/
|
||||||
|
|
||||||
|
|
||||||
|
$("#submitBtn").click(function(){
|
||||||
|
var edo = parseInt($("#edo").val());
|
||||||
|
console.log(edo)
|
||||||
|
if((edo == 3 && valida()) || edo == 2){
|
||||||
|
$("#formaModal").submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function validaFiltro(){
|
||||||
|
if($('#filter_fecha_ini').val() != "" && !validaFecha($('#filter_fecha_ini').val()) ){
|
||||||
|
$('#filter_fecha_ini').addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if($('#filter_fecha_fin').val() != "" && !validaFecha($('#filter_fecha_fin').val())){
|
||||||
|
$('#filter_fecha_fin').addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if($('#filter_fecha_ini').val() != "" && $('#filter_fecha_fin').val() != "" && fechaMayor($('#filter_fecha_ini').val(), $('#filter_fecha_fin').val()) >= 0){
|
||||||
|
$('#filter_fecha_fin').addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('[data-toggle="tooltip"]').tooltip()
|
||||||
|
});
|
||||||
|
|
||||||
|
/**@Auxiliary functions */
|
||||||
|
function listProfesor({
|
||||||
|
id,
|
||||||
|
grado,
|
||||||
|
profesor,
|
||||||
|
clave
|
||||||
|
}) {
|
||||||
|
const lista = document.getElementById("dlProfesor");
|
||||||
|
lista.innerHTML = "";
|
||||||
|
lista.classList.remove("is-invalid");
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.setAttribute('data-id', id);
|
||||||
|
li.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center');
|
||||||
|
li.innerHTML = `${clave} | ${grado ?? ''} ${profesor}`
|
||||||
|
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.setAttribute('type', 'button');
|
||||||
|
btn.classList.add('badge', 'badge-danger', 'badge-pill', 'border-0');
|
||||||
|
btn.onclick = _ => li.remove();
|
||||||
|
|
||||||
|
const i = document.createElement('i');
|
||||||
|
i.classList.add('ing-cancelar');
|
||||||
|
btn.appendChild(i);
|
||||||
|
li.appendChild(btn);
|
||||||
|
|
||||||
|
document.getElementById("profesores").appendChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
function listSalon({
|
||||||
|
id,
|
||||||
|
nombre
|
||||||
|
}) {
|
||||||
|
const lista = document.getElementById("dlSalon");
|
||||||
|
lista.innerHTML = "";
|
||||||
|
lista.classList.remove("is-invalid");
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.setAttribute('data-id', id);
|
||||||
|
li.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center');
|
||||||
|
li.innerHTML = `${nombre}`
|
||||||
|
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.setAttribute('type', 'button');
|
||||||
|
btn.classList.add('badge', 'badge-danger', 'badge-pill', 'border-0');
|
||||||
|
btn.onclick = _ => li.remove();
|
||||||
|
|
||||||
|
const i = document.createElement('i');
|
||||||
|
i.classList.add('ing-cancelar');
|
||||||
|
btn.appendChild(i);
|
||||||
|
li.appendChild(btn);
|
||||||
|
|
||||||
|
document.getElementById("salones").appendChild(li);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
933
reposiciones_crear.php
Normal file
933
reposiciones_crear.php
Normal file
@@ -0,0 +1,933 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'class/c_login.php';
|
||||||
|
if (!isset($_SESSION['user'])){
|
||||||
|
die(header('Location: index.php'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = unserialize($_SESSION['user']);
|
||||||
|
if (!$user->profesor && !$user->admin){
|
||||||
|
die(header('Location: index.php'));
|
||||||
|
}
|
||||||
|
$user->access();
|
||||||
|
//if (!$user->admin && in_array($user->acceso, ['n']))
|
||||||
|
//die(header('Location: main.php?error=1'));
|
||||||
|
$user->print_to_log('Reposiciones');
|
||||||
|
|
||||||
|
//$write = $user->admin || in_array($user->acceso, ['w']);
|
||||||
|
$write = true; //
|
||||||
|
|
||||||
|
$en_fecha = $db->querySingle("SELECT ESTA_EN_PERIODO(NOW()::DATE, :periodo_id)", [':periodo_id' => $user->periodo_id])['esta_en_periodo'];
|
||||||
|
|
||||||
|
$prof_rs = $db->query('SELECT * FROM profesor A WHERE EXISTS (
|
||||||
|
SELECT * FROM horario_view hv join HORARIO_PROFESOR ON hv.HORARIO_ID = HORARIO_PROFESOR.horario_id WHERE HORARIO_PROFESOR.profesor_id = A.profesor_id AND hv.periodo_id = :periodo_id
|
||||||
|
) ORDER BY profesor_nombre', [':periodo_id' => $user->periodo_id]);
|
||||||
|
|
||||||
|
|
||||||
|
//Periodo
|
||||||
|
$periodo_rs = $db->querySingle('SELECT periodo_fecha_inicio, periodo_fecha_fin FROM periodo WHERE periodo_id = :periodo_id', [':periodo_id' => $user->periodo_id]);
|
||||||
|
$periodo_fin = $periodo_rs["periodo_fecha_fin"];
|
||||||
|
if(strtotime($periodo_rs["periodo_fecha_inicio"])>strtotime(date("Y-m-d")) )
|
||||||
|
$fecha_man = date("d/m/Y", strtotime($periodo_rs["periodo_fecha_inicio"]));
|
||||||
|
else{
|
||||||
|
$dias = 3;
|
||||||
|
if( intval(date("w")) >=3 && intval(date("w"))<=5 )//Mie a Vie
|
||||||
|
$dias+=3;
|
||||||
|
else if( intval(date("w")) ==6 )//Sab
|
||||||
|
$dias+=2;
|
||||||
|
else if( intval(date("w")) ==0 )//Do
|
||||||
|
$dias+=1;
|
||||||
|
|
||||||
|
$fecha_man = date("d/m/Y", strtotime("+".$dias." day"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Materias
|
||||||
|
//$id_prof = $user->user["id"];
|
||||||
|
$id_prof = 2142;
|
||||||
|
//$facultad_id = 28;
|
||||||
|
$materias_rs = $db->query('SELECT * FROM fs_materiasprofesor(:id)', [':id' => $id_prof]);
|
||||||
|
|
||||||
|
if(isset($_POST["fecha_inicial"]))
|
||||||
|
$fecha_ini = $_POST["fecha_inicial"];
|
||||||
|
else
|
||||||
|
$fecha_ini = date("d/m/Y", strtotime($periodo_rs["periodo_fecha_inicio"]));
|
||||||
|
|
||||||
|
if(isset($_POST["fecha_final"]))
|
||||||
|
$fecha_fin = $_POST["fecha_final"];
|
||||||
|
else
|
||||||
|
$fecha_fin = date("d/m/Y", strtotime($periodo_rs["periodo_fecha_fin"]));
|
||||||
|
|
||||||
|
$fecha_ini_db= date("Y-m-d", strtotime($fecha_ini));
|
||||||
|
$fecha_fin_db= date("Y-m-d", strtotime($fecha_fin));
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Reposiciones crear | <?= $user->facultad['facultad'] ?? 'General' ?></title>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="content-type" content="text/plain; 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"; ?>
|
||||||
|
<link rel="stylesheet" href="css/jquery-ui.css">
|
||||||
|
<link rel="stylesheet" href="css/richtext.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="css/clockpicker.css">
|
||||||
|
<link rel="stylesheet" href="css/calendar.css">
|
||||||
|
<link rel="stylesheet" href="css/fa_all.css" type="text/css">
|
||||||
|
|
||||||
|
<script src="js/scrollables.js" defer></script>
|
||||||
|
<script>
|
||||||
|
const write = <?= $write ? 'true' : 'false' ?>;
|
||||||
|
</script>
|
||||||
|
<script src="js/moment.js" defer></script>
|
||||||
|
<style>
|
||||||
|
.wizard { height: 20px; width: 80%; background: #D0D0D0; }
|
||||||
|
.wizard.full { background: #D0D0D0; }
|
||||||
|
.wizard.active > div:first-child { background: #00A6CE; }
|
||||||
|
.wizard.active > div:last-child { width: 0px; height: 0px; border-style: solid; border-width: 10px 0 10px 6px; border-color: transparent transparent transparent #00a6ce; transform: rotate(0deg); }
|
||||||
|
</style>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/bootstrap/popper.min.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="js/datepicker-es.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<body style="display: block;">
|
||||||
|
<?php
|
||||||
|
include('include/constantes.php');
|
||||||
|
include("import/html_header.php");
|
||||||
|
html_header("Reposiciones de clase", "Sistema de gestión de checador");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="container content marco content-margin" id="local-app">
|
||||||
|
<?php if($write==true ) {?>
|
||||||
|
<!-- Botón para abrir el modal -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12 text-right">
|
||||||
|
<button type="button" class="btn btn-outline-secondary" data-tipo="1" data-toggle="modal" data-target="#modal" <?php if (!$en_fecha || (empty($materias_rs) || count($materias_rs)==0 ) ){ echo "disabled"; } ?>><span class="ing-mas ing-fw"></span>Crear reposición</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php }?>
|
||||||
|
<section id="message"></section>
|
||||||
|
<?php require('import/periodo.php') ?>
|
||||||
|
|
||||||
|
<form id="asistencia" method="post" onsubmit="return validaFechas()">
|
||||||
|
<div class="form-box">
|
||||||
|
<input type="hidden" name="facultad" value="">
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="filtro_inicial" class="col-4 col-form-label">Fecha inicial</label>
|
||||||
|
<div class="col-8 col-sm-4">
|
||||||
|
<input id="filtro_inicial" name="fecha_inicial" type="text" class="form-control date-picker-filtro" placeholder="dd/mm/aaaa" maxlength="10" required="required" readonly="" value="<?php echo $fecha_ini;?>">
|
||||||
|
<div class="invalid-feedback">No es una fecha válida.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="filtro_final" class="col-4 col-form-label">Fecha final</label>
|
||||||
|
<div class="col-8 col-sm-4">
|
||||||
|
<input id="filtro_final" name="fecha_final" type="text" class="form-control date-picker-filtro" placeholder="dd/mm/aaaa" maxlength="10" required="required" readonly="" value="<?php echo $fecha_fin;?>">
|
||||||
|
<div class="invalid-feedback">El rango de fechas no es válido.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row justify-content-center">
|
||||||
|
<button type="submit" class="btn btn-outline-primary mr-2" id="btn-buscar"><span class="ing-buscar ing-fw"></span> Buscar</button>
|
||||||
|
<button type="button" class="btn btn-outline-danger" onclick="window.location.href = window.location.href"><span class="ing-borrar ing-fw"></span> Limpiar</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$reposiciones_rs = $db->query('SELECT * FROM fs_reposicionesprofesor(:f_ini, :f_fin, NULL, NULL)', [':f_ini' => $fecha_ini_db, ':f_fin' => $fecha_fin_db]);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php
|
||||||
|
if(isset($reposiciones_rs) && count($reposiciones_rs)>0){ ?>
|
||||||
|
<h3 class="mb-3">Mis reposiciones</h3>
|
||||||
|
<div class="col-12 table-responsive px-0">
|
||||||
|
<table class="table table-sm table-striped table-white">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr >
|
||||||
|
<th>Estado</th>
|
||||||
|
<th>Materia</th>
|
||||||
|
<th>Tipo</th>
|
||||||
|
<th style="width:160px">Fecha falta</th>
|
||||||
|
<th style="width:160px">Fecha reposición</th>
|
||||||
|
<th>Salón</th>
|
||||||
|
<?php if($write){ ?><th>Acciones</th><?php } ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
foreach($reposiciones_rs as $reposicion){
|
||||||
|
?>
|
||||||
|
<tr data-id="<?php echo $reposicion["reposicion_id"]; ?>" id="id<?php echo $reposicion["reposicion_id"]; ?>">
|
||||||
|
<td class="align-middle text-center" style="color:<?php echo $reposicion["estado_color"];?>" title="<?php echo $reposicion["estado_nombre"];?>">
|
||||||
|
<?php if($reposicion["estado_reposicion_id"]<3){ ?>
|
||||||
|
<div class="wizard <?php if(intval($reposicion["estado_reposicion_id"])==2) echo "active";?> d-flex mx-auto">
|
||||||
|
<div class="w-50 h-100"></div>
|
||||||
|
<div class=""></div>
|
||||||
|
</div>
|
||||||
|
<?php } else if($reposicion["estado_reposicion_id"]==3){?>
|
||||||
|
<div class="text-success text-center pt-1">
|
||||||
|
<span class="ing-autorizar ing-lg"></span>
|
||||||
|
</div>
|
||||||
|
<?php } else {?>
|
||||||
|
<div class="text-danger text-center pt-1">
|
||||||
|
<span class="ing-negar ing-lg"></span>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle"><?php echo $reposicion["materia_nombre"]; ?></td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<?php if($reposicion["es_reposicion"]) echo "Reposición"; else echo "Cambio"; ?>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle text-center"><?php
|
||||||
|
echo date("d/m/Y", strtotime($reposicion["fecha_clase"]));
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle text-center"><?php
|
||||||
|
|
||||||
|
echo date("d/m/Y", strtotime($reposicion["fecha_nueva"])) ."<br>".substr($reposicion["hora_nueva"],0,-3)." a ".substr($reposicion["hora_nueva_fin"],0,-3)." hrs.";
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle text-center"><?php
|
||||||
|
if($reposicion["salon_id"] != ""){
|
||||||
|
echo $reposicion["salon_id"];
|
||||||
|
}else
|
||||||
|
echo "Pendiente";
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<?php if($write){ ?>
|
||||||
|
<td class="align-middle text-center icono-acciones">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
//no se ha aprobado
|
||||||
|
if($reposicion["estado_reposicion_id"] == 1){?>
|
||||||
|
<a href="#" data-tipo="2" title="Editar" data-toggle="modal" data-target="#modal"><?php echo $ICO["editar"];?></a>
|
||||||
|
<a href="#" data-toggle="modal" data-target="#modal_confirm" title="Borrar"><?php echo $ICO["cancelar"];?></a>
|
||||||
|
<?php } ?>
|
||||||
|
</td>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
<?php }
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php } else { ?>
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<h4 class="mt-4 text-danger">No tienes reposiciones disponibles que cumplan con los filtros</h4>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="col-12 modal-title text-center"><span id="modalLabel">Crear Reposición</span>
|
||||||
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button></h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="./action/reposicion_insert.php" method="post" id="formaModal" onsubmit="return submitForm()">
|
||||||
|
<input type="hidden" name="id" id="id">
|
||||||
|
<input type="hidden" name="estado" value="1">
|
||||||
|
<div class="form-box">
|
||||||
|
|
||||||
|
<div class="form-group row <?php if(true){ echo "d-none"; }?>" id="profBlock">
|
||||||
|
<label for="prof" class="col-4 col-form-label">Profesor *</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<div class="datalist datalist-select mb-1 w-100" id="dlProfesor">
|
||||||
|
<div class="datalist-input">Profesores del área</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<?php foreach($prof_rs as $prof){?>
|
||||||
|
<li data-id="<?php echo $prof["id"];?>" <?php if($prof["id"]==$_SESSION["usuario_id"]){ echo "class='selected'";} ?> ><?php echo $prof["profesor"];?></li>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="prof" name="prof" value="<?php echo $id_prof;?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group row" id="materiaBlock">
|
||||||
|
<label for="horario" class="col-4 col-form-label">Materia *</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<div class="datalist datalist-select mb-1 w-100" id="dlMateria">
|
||||||
|
<div class="datalist-input">Selecciona una materia</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<?php foreach($materias_rs as $mat){ ?>
|
||||||
|
<li data-id="<?php echo $mat["horario_id"];?>" data-dia="<?php echo $mat["horario_dia"];?>" data-hr="<?php echo substr($mat["horario_hora"], 0, 2);?>" data-min="<?php echo substr($mat["horario_hora"], 3, 2);?>">
|
||||||
|
<?php echo $mat["materia_nombre"].' - '.$mat["horario_dia_nombre"]." ".substr($mat["horario_hora"], 0, -3);?>
|
||||||
|
</li>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="horario" name="horario" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="tipo" class="col-4 col-form-label">Tipo *</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<div class="datalist datalist-select mb-1 w-100" id="dlTipo">
|
||||||
|
<div class="datalist-input">Reposición</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<li data-id="1">Reposición</li>
|
||||||
|
<li data-id="2">Cambio de salón</li>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="tipo" name="tipo" value="1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row cambio_block materia-block" style="display: none;">
|
||||||
|
<label for="fecha_cambio" class="col-4 col-form-label">Fecha de cambio *</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<input id="fecha_cambio" name="fecha_cambio" type="text" class="form-control date-picker" placeholder="dd/mm/aaaa" maxlength="10" required="required" readonly="readonly" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row repo_block materia-block">
|
||||||
|
<label for="fecha_falta" class="col-4 col-form-label">Fecha de falta *</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<input id="fecha_falta" name="fecha_falta" type="text" class="form-control date-picker" placeholder="dd/mm/aaaa" maxlength="10" required="required" readonly="readonly" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row repo_block materia-block">
|
||||||
|
<label for="fecha_inicial" class="col-4 col-form-label">Fecha de reposicion *</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<input id="fecha_inicial" name="fecha_inicial" type="text" class="form-control date-picker-future" placeholder="dd/mm/aaaa" maxlength="10" required="required" readonly="readonly" value="">
|
||||||
|
<small class="form-text text-muted">Las reposiciones se deben solicitar con al menos 72hrs de anticipación.<br>
|
||||||
|
Si repones en sábado, consulta los horarios con tu jefe de carrera.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row materia-block">
|
||||||
|
<label for="hora_ini" class="col-4 col-form-label" id="hora_nombre">Hora reposición *</label>
|
||||||
|
<?php
|
||||||
|
//define("HORA_FINAL", 22);
|
||||||
|
//define("FRACCION_HORA", 15);
|
||||||
|
$default_h = 7; $default_m = 15;
|
||||||
|
?>
|
||||||
|
<div class="col-4">
|
||||||
|
<select name="hora_ini" id="hora_ini" class="form-control" required="required">
|
||||||
|
<?php for($h = $default_h; $h < HORA_FINAL; $h++){?>
|
||||||
|
<option value="<?php echo sprintf( '%02d', $h );?>" <?php if($default_h == $h){ echo 'selected="selected"';}?>><?php echo sprintf( '%02d', $h );?></option>
|
||||||
|
<?php } ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<select name="min_ini" id="min_ini" class="form-control" required="required">
|
||||||
|
<?php for($m = 0; $m < 60; $m+=(60/FRACCION_HORA)){?>
|
||||||
|
<option value="<?php echo sprintf( '%02d', $m );?>" <?php if($default_m == $m){ echo 'selected="selected"';}?>><?php echo sprintf( '%02d', $m );?></option>
|
||||||
|
<?php } ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group row materia-block">
|
||||||
|
<label for="salon" class="col-4 col-form-label">Alumnos aproximados *</label>
|
||||||
|
<div class="col-8 col-md-4">
|
||||||
|
<input type="number" name="alumnos" id="alumnos" class="form-control" value="1" min="1" max="50">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row materia-block">
|
||||||
|
<label for="aula" class="col-4 col-form-label">Tipo aula *</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<div class="datalist datalist-select mb-1 w-100" id="dlAula">
|
||||||
|
<div class="datalist-input">Salón</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<li data-id="1">Salón</li>
|
||||||
|
<li data-id="2">Sala de cómputo</li>
|
||||||
|
<li data-id="3">Salón/Taller de la facultad</li>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="aula" name="aula" value="1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-box form-box-info materia-block">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="comentario" class="col-4 col-form-label">Comentarios</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<p><i>Requerimientos específicos del salón, software especializado, etc.</i></p>
|
||||||
|
<textarea rows="3" class="form-control" id="comentario" name="comentario"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<div class="offset-4 col-8">
|
||||||
|
<button type="submit" class="btn btn-outline-primary materia-block" id="submitBtn" data-tipo="1"><?php echo $ICO["aceptar"];?> Guardar</button>
|
||||||
|
<button type="reset" class="btn btn-outline-danger" data-dismiss="modal"><?php echo $ICO["cancelar"];?> Cancelar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Modal del formulario -->
|
||||||
|
<div class="modal fade" id="crearReposiciónOld" tabindex="-1" role="dialog" aria-labelledby="crearReposiciónLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="crearReposiciónLabel">Crear Reposición</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="form" class="form-horizontal">
|
||||||
|
<div class="form-group step" id="step-1">
|
||||||
|
<div class="form-box">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="clave_profesor" class="col-4 col-form-label">Profesor</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<input list="lista_profesores" name="clave_profesor" id="clave_profesor" class="form-control" placeholder="Profesor" required="required">
|
||||||
|
<div class="valid-feedback">
|
||||||
|
Profesor encontrado
|
||||||
|
</div>
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
Profesor no encontrado
|
||||||
|
</div>
|
||||||
|
<datalist id="lista_profesores">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
foreach ($prof_rs as $prof) {
|
||||||
|
?>
|
||||||
|
<option data-grado="<?= $prof["profesor_grado"] ?>" data-clave="<?= $prof["profesor_clave"] ?>" data-profesor="<?= $prof["profesor_nombre"] ?>" data-id="<?= $prof["profesor_id"]; ?>" value="<?= "{$prof["profesor_clave"]} | {$prof["profesor_grado"]} {$prof["profesor_nombre"]}" ?>"></option>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</datalist>
|
||||||
|
<ul class="list-group" id="profesores"></ul>
|
||||||
|
<input type="hidden" id="periodo_id" name="periodo_id" value="<?= $user->periodo_id ?>">
|
||||||
|
<input type="hidden" id="profesor_id" name="profesor_id" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group step" id="step-2">
|
||||||
|
<div class="form-box">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="horario_reponer" class="col-4 col-form-label">Horario a reponer</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<select name="horario_reponer" id="horario_reponer" class="form-control" required="required">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="horario_id" id="horario_id">
|
||||||
|
</div>
|
||||||
|
<div class="form-group step" id="step-3">
|
||||||
|
<div class="form-box">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="fechas_clase" class="col-4 col-form-label">Fecha de clase</label>
|
||||||
|
<div class="col-8">
|
||||||
|
<select name="fechas_clase" id="fechas_clase" class="form-control" required="required">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group step" id="step-4">
|
||||||
|
<div class="form-box">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="fecha_reponer" class="col-4 col-form-label">Fecha de reposición</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="text" placeholder="dd/mm/aaaa" name="fecha_reponer" id="fecha_reponer" class="form-control date-picker" required="required">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="hora" class="col-4 col-form-label">Hora</label>
|
||||||
|
<div class="col-3">
|
||||||
|
<div id="hora" class="datalist datalist-select mb-1">
|
||||||
|
<div class="datalist-input text-center">hh</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<?php foreach (range(7, 21) as $hora) { ?>
|
||||||
|
<li data-id='<?= $hora ?>'><?= str_pad($hora, 2, "0", STR_PAD_LEFT) ?></li>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="hora_reponer" name="horas" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<div id="minutos" class="datalist datalist-select mb-1">
|
||||||
|
<div class="datalist-input text-center">mm</div>
|
||||||
|
<span class="ing-buscar icono"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<?php foreach (range(0, 45, 15) as $minuto) { ?>
|
||||||
|
<li data-id='<?= $minuto ?>'><?= str_pad($minuto, 2, "0", STR_PAD_LEFT) ?></li>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="minutos_reponer" name="minutos" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group step" id="step-5">
|
||||||
|
<div class="form-box">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="descripcion_reposicion" class="col-4 col-form-label">Comentarios</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<textarea name="descripcion_reposicion" id="descripcion_reposicion" rows="4" required="required" placeholder="Se requiere proyector, etc." maxlength="255" class="form-control"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row align-items-center">
|
||||||
|
<label class="col-4 col-form-label" for="sala">¿En sala de cómputo?</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="sala">
|
||||||
|
<label class="custom-control-label" for="sala"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer justify-content-center">
|
||||||
|
<button class="btn btn-secondary" type="button" id="prev-button">Anterior</button>
|
||||||
|
<button class="btn btn-secondary" type="button" id="next-button" disabled data-toggle="modal" data-target="#confirmationModal">Proponer reposición</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal confirmación -->
|
||||||
|
<div class="modal fade" id="confirmationModal" tabindex="-1" role="dialog" aria-labelledby="confirmationModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-sm" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="confirmationModalLabel">Confirmación</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>¿Estás seguro de que deseas proponer la reposición?</p>
|
||||||
|
<small>Recuerda que la aprobará tu jefe de carrera.</small>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-info" onclick="$('#confirmationModal').modal('hide');">Cancelar</button>
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal">Aceptar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="modal_confirm" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<p class="font-weight-bold">¿Estás seguro de que quieres borrar la reposición?</p>
|
||||||
|
<p>Esta acción no se puede deshacer.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<input type="hidden" id="id_borrar" value="">
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-borrar"><?php echo $ICO["aceptar"];?> Borrar</button>
|
||||||
|
<button type="button" class="btn btn-outline-danger" data-dismiss="modal" aria-label="Close"><?php echo $ICO["cancelar"];?> Cancelar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
//--Manejo de errores y mensajes de exito
|
||||||
|
if(isset($_GET["error"]) && is_numeric($_GET["error"])){
|
||||||
|
switch ($_GET["error"]){
|
||||||
|
case 0: $errorDesc = "No se reciberon los datos de la reposición."; break;
|
||||||
|
case 1: $errorDesc = "Ocurrió un error al insertar los datos de la reposición/cambio."; break;
|
||||||
|
case 2: $errorDesc = "Ocurrió un error al actualizar los datos de la reposición/cambio."; break;
|
||||||
|
case 3: $errorDesc = "No tienes permisos para realizar esa acción."; break;
|
||||||
|
case 4: $errorDesc = "Ocurrió un error al cargar los datos de la reposición/cambio."; break;
|
||||||
|
case 6: $errorDesc = "La reposición/cambio que buscas no existe. Consulta la lista de reopsiciones disponibles en esta sección."; break;
|
||||||
|
case 7: $errorDesc = "La reposición/cambio se empalma con el horario del grupo y no se puede guardar."; break;
|
||||||
|
case 8: $errorDesc = "El salón de la reposición está siendo utilizado ese día a esa hora y no se puede guardar."; break;
|
||||||
|
case 9: $errorDesc = "El profesor está asigndo a otra reposición/cambio el mismo día a la misma hora y no se puede guardar."; break;
|
||||||
|
case 10: $errorDesc = "El profesor está asigndo a una materia el mismo día a la misma hora y no se puede guardar."; break;
|
||||||
|
case 11: $errorDesc = "No hay clases asignadas para esa materia y grupo en la fecha de falta."; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isset($_GET["ok"]) && is_numeric($_GET["ok"])){
|
||||||
|
switch ($_GET["ok"]){
|
||||||
|
case 0: $successDesc = "La reposición se guardó correctamente."; break;
|
||||||
|
case 1: $successDesc = "La reposición se actualizó correctamente."; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require_once 'js/messages.php';
|
||||||
|
?>
|
||||||
|
<script>
|
||||||
|
<?php if(isset($errorDesc)){ ?>
|
||||||
|
triggerMessage("<?php echo $errorDesc;?>", "Error");
|
||||||
|
<?php } else if(isset($successDesc)){ ?>
|
||||||
|
triggerMessage("<?php echo $successDesc;?>", "Éxito", "success");
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
var vacaciones=[
|
||||||
|
<?php /*foreach($vacacionesArr as $v){ echo '"'.$v["fecha"].'",';}*/ ?>
|
||||||
|
];
|
||||||
|
var _dias_asistencia = [];//ya registró asistencia, cambia con ajax
|
||||||
|
var _dia_valido = 0;
|
||||||
|
var _fecha_manhana = "<?php echo $fecha_man; ?>";
|
||||||
|
var _periodo_fecha_inicial = "<?php echo date("d/m/Y", strtotime($periodo_rs["periodo_fecha_inicio"])); ?>";
|
||||||
|
var _periodo_fecha_final = "<?php echo date("d/m/Y", strtotime($periodo_rs["periodo_fecha_fin"])); ?>";
|
||||||
|
var datepickerOptions_filtro = { dateFormat: "dd/mm/yy", minDate:_periodo_fecha_inicial, maxDate:_periodo_fecha_final};
|
||||||
|
|
||||||
|
var datepickerOptions = { dateFormat: "dd/mm/yy", minDate:_periodo_fecha_inicial, maxDate:_periodo_fecha_final,
|
||||||
|
beforeShowDay: function(date) {
|
||||||
|
var day = date.getDay();
|
||||||
|
var dateString = $.datepicker.formatDate("yy-mm-dd", date);
|
||||||
|
if (day === _dia_valido) {// 0 representa el domingo
|
||||||
|
if (vacaciones.indexOf(dateString) !== -1 || _dias_asistencia.indexOf(dateString) !== -1)
|
||||||
|
return [false];
|
||||||
|
else
|
||||||
|
return [true];
|
||||||
|
}else{
|
||||||
|
return [false];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var datepickerOptions_future = { dateFormat: "dd/mm/yy", minDate:_fecha_manhana, maxDate:_periodo_fecha_final,
|
||||||
|
beforeShowDay: function(date) {
|
||||||
|
var day = date.getDay();
|
||||||
|
var dateString = $.datepicker.formatDate("yy-mm-dd", date);
|
||||||
|
if (day === 0) {// 0 representa el domingo
|
||||||
|
return [false];
|
||||||
|
} else {
|
||||||
|
if (vacaciones.indexOf(dateString) !== -1) {
|
||||||
|
return [false];
|
||||||
|
} else {
|
||||||
|
return [true];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function diaAAno(fecha_str){//de dd/mm/yyyy a yyyy-mm-dd
|
||||||
|
if(fecha_str.charAt(2) == "/" && fecha_str.charAt(5) == "/"){//dd/mm/yyyy
|
||||||
|
var fecha_arr = fecha_str.split("/");
|
||||||
|
return fecha_arr[2]+"-"+fecha_arr[1]+"-"+fecha_arr[0];
|
||||||
|
}
|
||||||
|
return fecha_str;
|
||||||
|
}
|
||||||
|
function fechaMayor(fechaI, fechaF) {//cual es mayor >0 I mayor <0 F mayor
|
||||||
|
return (Date.parse(diaAAno(fechaI)) - Date.parse(diaAAno(fechaF)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function validaFechas(){
|
||||||
|
if(fechaMayor($('#filtro_inicial').val().trim(), $('#filtro_final').val().trim()) > 0){
|
||||||
|
$('#filtro_final').addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitForm(){
|
||||||
|
var myBtn = $('#submitBtn');
|
||||||
|
var error = false;
|
||||||
|
|
||||||
|
$("#gpo").removeClass("is-invalid");
|
||||||
|
invalidDatalist("#materia", false);
|
||||||
|
$("#fecha_inicial").removeClass("is-invalid");
|
||||||
|
$("#fecha_falta").removeClass("is-invalid");
|
||||||
|
$("#fecha_cambio").removeClass("is-invalid");
|
||||||
|
|
||||||
|
|
||||||
|
if($("#tipo").val() == 1){//reposición
|
||||||
|
if($("#fecha_falta").val() == ""){
|
||||||
|
$("#fecha_falta").addClass("is-invalid");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
if($("#fecha_inicial").val() == ""){//fecha reposición
|
||||||
|
$("#fecha_inicial").addClass("is-invalid");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if($("#fecha_cambio").val() == ""){
|
||||||
|
$("#fecha_cambio").addClass("is-invalid");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($("#horario").val().trim() == "" || $("#horario").val() === null){
|
||||||
|
invalidDatalist("#horario", true);
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(myBtn.data("tipo") == 2 ){
|
||||||
|
$('#formaModal').prop("action", "./action/reposicion_update.php");
|
||||||
|
}else{
|
||||||
|
$('#formaModal').prop("action", "./action/reposicion_insert.php");
|
||||||
|
}
|
||||||
|
return !error;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cambiaTipo(tipo){
|
||||||
|
if (tipo == 1){//reposición
|
||||||
|
$(".repo_block").show();
|
||||||
|
$(".cambio_block").hide();
|
||||||
|
$(".repo_block").find("input[type=text]").attr("required", true);
|
||||||
|
$(".cambio_block").find("input[type=text]").removeAttr("required");
|
||||||
|
$("#hora_nombre").text("Hora reposición *");
|
||||||
|
}else{//Cambio de salón
|
||||||
|
$(".repo_block").hide();
|
||||||
|
$(".cambio_block").show();
|
||||||
|
$(".repo_block").find("input[type=text]").removeAttr("required");
|
||||||
|
$(".cambio_block").find("input[type=text]").attr("required", true);
|
||||||
|
$("#hora_nombre").text("Hora cambio *");
|
||||||
|
var hora = $("#dlMateria ul li.selected").data("hr");
|
||||||
|
var min = $("#dlMateria ul li.selected").data("min");
|
||||||
|
$("#hora_ini").val(hora)
|
||||||
|
$("#min_ini").val(min)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
//fecha de clase
|
||||||
|
$(".date-picker" ).datepicker(datepickerOptions);
|
||||||
|
$(".date-picker" ).datepicker( $.datepicker.regional[ "es" ] );
|
||||||
|
|
||||||
|
//fecha de clase
|
||||||
|
$(".date-picker-filtro" ).datepicker(datepickerOptions_filtro);
|
||||||
|
$(".date-picker-filtro" ).datepicker( $.datepicker.regional[ "es" ] );
|
||||||
|
|
||||||
|
//fecha nueva
|
||||||
|
$(".date-picker-future" ).datepicker(datepickerOptions_future);
|
||||||
|
$(".date-picker-future" ).datepicker( $.datepicker.regional[ "es" ] );
|
||||||
|
|
||||||
|
<?php if(/*$_SESSION["jefe_carrera"] ||*/ $user->admin){ ?>
|
||||||
|
function creaOpcion(id_lista, nombre, gpo, dia, hora){
|
||||||
|
return '<li data-id="'+id_lista+'" >'+nombre+' ('+gpo+') - '+dia+' '+hora.substr(0, 5)+'</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#filtro_final').focus(function(){
|
||||||
|
$("#filtro_final").removeClass("is-invalid");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#dlProfesor ul li").click(function(){//cambia datalist
|
||||||
|
var pid = $(this).data('id');
|
||||||
|
//busca materias del profesor
|
||||||
|
$.ajax({
|
||||||
|
url: './action/materiasdiaprofesor_select.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { id: pid, },
|
||||||
|
success: function(result) {
|
||||||
|
if(result["error"]!= "" && result["error"] !== undefined){
|
||||||
|
triggerMessage(result["error"], "Error");
|
||||||
|
$("#modal").modal('hide');
|
||||||
|
}else{
|
||||||
|
$("#dlMateria ul").html("");
|
||||||
|
for(i=0; i<result["materias"].length; i++){
|
||||||
|
var html = creaOpcion(result["materias"][i]["Horario_id"],
|
||||||
|
result["materias"][i]["Materia_desc"],
|
||||||
|
result["materias"][i]["Grupo_desc"]+" "+result["materias"][i]["Carrera_prefijo"],
|
||||||
|
result["materias"][i]["Dia_desc"],
|
||||||
|
result["materias"][i]["Hora_inicio"]
|
||||||
|
);
|
||||||
|
$("#dlMateria ul").append(html);
|
||||||
|
}
|
||||||
|
setDatalistFirst("#horario");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown ){
|
||||||
|
triggerMessage(errorThrown, "Error");
|
||||||
|
}
|
||||||
|
});//ajax
|
||||||
|
|
||||||
|
});
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
//Actualiza días elegibles de calendario
|
||||||
|
$("#dlMateria ul li").click(function(){//cambia datalist
|
||||||
|
_dia_valido = $(this).data('dia');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: './action/asistenciasprofesor_select.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { "id": $("#prof").val(), "hor": $(this).data("id") },
|
||||||
|
success: function(result) {
|
||||||
|
if(result["error"]!= "" && result["error"] !== undefined){
|
||||||
|
triggerMessage(result["error"], "Error");
|
||||||
|
$('#modal').modal("hide");
|
||||||
|
}else{
|
||||||
|
_dias_asistencia = result["asistenciaArr"];
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown ){
|
||||||
|
triggerMessage(errorThrown, "Error");
|
||||||
|
}
|
||||||
|
});//ajax
|
||||||
|
|
||||||
|
$(".date-picker" ).datepicker(datepickerOptions);
|
||||||
|
var hora = $(this).data("hr");
|
||||||
|
var min = $(this).data("min");
|
||||||
|
$("#hora_ini").val(hora)
|
||||||
|
$("#min_ini").val(min)
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#dlTipo ul li").click(function(){//cambia datalist
|
||||||
|
cambiaTipo($(this).data('id'));
|
||||||
|
$(".date-picker" ).datepicker(datepickerOptions);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modal_confirm').on('show.bs.modal', function (event) {
|
||||||
|
var button = $(event.relatedTarget); // Button that triggered the modal
|
||||||
|
var id = button.parents("tr").data("id");
|
||||||
|
$("#id_borrar").val(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".btn-borrar").click(function(){
|
||||||
|
var r_id = $("#id_borrar").val();
|
||||||
|
$.ajax({
|
||||||
|
url: './action/reposicion_delete.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { id: r_id},
|
||||||
|
success: function(result) {
|
||||||
|
if(result["error"]!= "" && result["error"] !== undefined){
|
||||||
|
triggerMessage(result["error"], "Error");
|
||||||
|
}else{
|
||||||
|
triggerMessage(result["ok"], "Éxito");
|
||||||
|
$("#id"+r_id).remove();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown ){
|
||||||
|
triggerMessage(errorThrown, "Error");
|
||||||
|
}
|
||||||
|
});//ajax
|
||||||
|
$('#modal_confirm').modal("hide");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#modal').on('show.bs.modal', function (event) {
|
||||||
|
var button = $(event.relatedTarget); // Button that triggered the modal
|
||||||
|
var tipo = button.data('tipo'); // 1 alta, 2 edicion
|
||||||
|
var modal = $(this);
|
||||||
|
|
||||||
|
$("#modal .is-invalid").removeClass("is-invalid");
|
||||||
|
//$(this).find(".form-control:first-child").focus();
|
||||||
|
|
||||||
|
$("#errorBox").collapse('hide');
|
||||||
|
$("#errorBox_text").html("");
|
||||||
|
if(tipo == 1){//alta
|
||||||
|
$("#submitBtn").data('tipo', 1);
|
||||||
|
$("#modalLabel").html("Crear Reposición");
|
||||||
|
modal.find("input[type=text]").val("");
|
||||||
|
modal.find("#alumnos").val("15");
|
||||||
|
$("#plan").attr("readonly", false);
|
||||||
|
$("#sem").attr("readonly", false);
|
||||||
|
$("#gpo").attr("readonly", false);
|
||||||
|
|
||||||
|
//$("#prof").attr("readonly", false);
|
||||||
|
disableDatalist("#horario", false);
|
||||||
|
disableDatalist("#tipo", false);
|
||||||
|
if($("#prof").length>0)
|
||||||
|
disableDatalist("#prof", false);
|
||||||
|
setDatalistFirst("#tipo");
|
||||||
|
setDatalistFirst("#aula");
|
||||||
|
setDatalistFirst("#horario");
|
||||||
|
$("#dlMateria ul li:first").click();
|
||||||
|
|
||||||
|
}else{//editar
|
||||||
|
$("#submitBtn").data('tipo', 2);
|
||||||
|
$("#modalLabel").html("Editar Reposición");
|
||||||
|
$("#plan").attr("readonly", true);
|
||||||
|
$("#sem").attr("readonly", true);
|
||||||
|
$("#gpo").attr("readonly", true);
|
||||||
|
//$("#materia").attr("readonly", true);
|
||||||
|
disableDatalist("#horario");
|
||||||
|
disableDatalist("#tipo");
|
||||||
|
/*if($("#prof").length>0)
|
||||||
|
disableDatalist("#prof");
|
||||||
|
$("#prof").attr("readonly", true);*/
|
||||||
|
var r_id = $(button).parents("tr").data("id");
|
||||||
|
$("#id").val(r_id);
|
||||||
|
$.ajax({
|
||||||
|
url: './action/reposicion_select.php',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { id: r_id },
|
||||||
|
success: function(result) {
|
||||||
|
if(result["error"]!= "" && result["error"] !== undefined){
|
||||||
|
triggerMessage(result["error"], "Error");
|
||||||
|
$("#modal").modal('hide');
|
||||||
|
}else{
|
||||||
|
//setDatalist("#prof", result["profesor"]);
|
||||||
|
$('#salon').val(result["salon"]);
|
||||||
|
$("#fecha_falta").val(result["fecha_clase"]);
|
||||||
|
$('#hora_ini').val(result["hora_ini"]);
|
||||||
|
$('#min_ini').val(result["min_ini"]);
|
||||||
|
$('#comentario').val(result["comentario"]);
|
||||||
|
$('#alumnos').val(result["alumnos"]);
|
||||||
|
setDatalist("#horario", result["horario"]);
|
||||||
|
setDatalist("#profesor", result["profesor"]);
|
||||||
|
if(result["tipo"]){
|
||||||
|
setDatalist("#tipo", 1);
|
||||||
|
cambiaTipo(1);
|
||||||
|
$("#fecha_inicial").val(result["fecha_nueva"]);
|
||||||
|
}else{
|
||||||
|
setDatalist("#tipo", 2);
|
||||||
|
cambiaTipo(2);
|
||||||
|
$("#fecha_cambio").val(result["fecha_nueva"]);
|
||||||
|
}
|
||||||
|
_dia_valido = parseInt(result["dia"]);
|
||||||
|
$(".date-picker" ).datepicker(datepickerOptions);
|
||||||
|
$("#dlTipo ul li:selected").click();
|
||||||
|
setDatalist("#aula", result["aula"]);
|
||||||
|
modal.modal('show');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown ){
|
||||||
|
triggerMessage(errorThrown, "Error");
|
||||||
|
$("#modal").modal('hide');
|
||||||
|
//$('#messageBox')[0].scrollIntoView({ block: "end" });
|
||||||
|
}
|
||||||
|
});//ajax
|
||||||
|
}
|
||||||
|
|
||||||
|
});//show
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('[data-toggle="tooltip"]').tooltip()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<script src="js/messages.js"></script>
|
||||||
|
<script type="module" src="js/reposiciones.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
10
roles.php
10
roles.php
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user'])){
|
|||||||
else
|
else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if(!$user->admin && $user->acceso == 'n'){
|
if($user->acceso == null){
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
}else{
|
}else{
|
||||||
$user->print_to_log('Roles');
|
$user->print_to_log('Roles');
|
||||||
@@ -40,11 +40,7 @@ echo $fac;
|
|||||||
"Gestión de Checador "
|
"Gestión de Checador "
|
||||||
);
|
);
|
||||||
$user->access();
|
$user->access();
|
||||||
$fs_roles = query(
|
$fs_roles = $db->orderBy('rol_titulo')->get('rol');
|
||||||
"SELECT * FROM rol ORDER BY rol_titulo",
|
|
||||||
null,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
?>
|
?>
|
||||||
<main class="content marco">
|
<main class="content marco">
|
||||||
<?php if($user->acceso == 'w'){?>
|
<?php if($user->acceso == 'w'){?>
|
||||||
@@ -60,7 +56,7 @@ echo $fac;
|
|||||||
<div class="col-12 table-responsive">
|
<div class="col-12 table-responsive">
|
||||||
<table class="table table-sm table-striped table-white">
|
<table class="table table-sm table-striped table-white">
|
||||||
<thead class="thead-dark">
|
<thead class="thead-dark">
|
||||||
<th>Titulo</th>
|
<th>Título</th>
|
||||||
<?php if($user->acceso == 'w'){?>
|
<?php if($user->acceso == 'w'){?>
|
||||||
<th>Acciones</th>
|
<th>Acciones</th>
|
||||||
<?php }?>
|
<?php }?>
|
||||||
|
|||||||
0
service/auditoria/index.php
Normal file
0
service/auditoria/index.php
Normal file
@@ -26,7 +26,7 @@
|
|||||||
"Sistema de gestión de checador",
|
"Sistema de gestión de checador",
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
<main class="container-fluid px-4" id="app" v-cloak @vue:mounted="mounted">
|
<main class="container-fluid px-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;">
|
||||||
<!-- error messages -->
|
<!-- error messages -->
|
||||||
<div class="container mb-4 mt-2">
|
<div class="container mb-4 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
140
ts/horario.ts
Normal file
140
ts/horario.ts
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
|
||||||
|
type Profesor = {
|
||||||
|
profesor_clave: string;
|
||||||
|
profesor_correo: string;
|
||||||
|
profesor_grado: null | string;
|
||||||
|
profesor_id: number;
|
||||||
|
profesor_nombre: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Horario = {
|
||||||
|
carrera: string;
|
||||||
|
carrera_id: number;
|
||||||
|
dia: string;
|
||||||
|
duracion: string;
|
||||||
|
duracion_id: number;
|
||||||
|
facultad: string;
|
||||||
|
facultad_id: number;
|
||||||
|
fecha_carga: Date;
|
||||||
|
horario_dia: number;
|
||||||
|
horario_fecha_fin: null;
|
||||||
|
horario_fecha_inicio: Date;
|
||||||
|
horario_fin: string;
|
||||||
|
horario_grupo: string;
|
||||||
|
horario_hora: string;
|
||||||
|
horario_id: number;
|
||||||
|
limite: null;
|
||||||
|
materia: string;
|
||||||
|
materia_id: number;
|
||||||
|
nivel: string;
|
||||||
|
nivel_id: number;
|
||||||
|
periodo: string;
|
||||||
|
periodo_fecha_fin: Date;
|
||||||
|
periodo_fecha_inicio: Date;
|
||||||
|
periodo_id: number;
|
||||||
|
profesor_id: number;
|
||||||
|
salon: string;
|
||||||
|
salon_id: number;
|
||||||
|
bloques: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const profesores = reactive({
|
||||||
|
data: [] as Profesor[],
|
||||||
|
search: null as null | string,
|
||||||
|
fetch: async function () {
|
||||||
|
const response = await fetch('action/action_profesor.php')
|
||||||
|
this.data = await response.json() as Profesor[]
|
||||||
|
},
|
||||||
|
get clave() {
|
||||||
|
const match = this.search.match(/^\((.+)\)/)
|
||||||
|
return match ? match[1] : ''
|
||||||
|
},
|
||||||
|
get current() {
|
||||||
|
return this.data.find((profesor: Profesor) => profesor.profesor_clave === profesores.clave)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
type Structure = {
|
||||||
|
sábado: boolean;
|
||||||
|
hora_mínima: number;
|
||||||
|
hora_máxima: number;
|
||||||
|
horas_totales: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const horarios = reactive({
|
||||||
|
data: [] as Horario[],
|
||||||
|
fetch: async function () {
|
||||||
|
if (profesores.current) {
|
||||||
|
const response = await fetch(`action/action_horario.php?profesor_id=${profesores.current.profesor_id}`)
|
||||||
|
this.data = await response.json()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get structure() {
|
||||||
|
if (this.data.length === 0) return null;
|
||||||
|
|
||||||
|
const structure: Structure = {
|
||||||
|
sábado: this.data.some((horario: Horario) => horario.horario_dia === 6),
|
||||||
|
hora_mínima: Math.min(...this.data.map((horario: Horario) => parseInt(horario.horario_hora.split(':')[0]))),
|
||||||
|
hora_máxima: Math.max(...this.data.map((horario: Horario) => {
|
||||||
|
const [hour, minute] = horario.horario_fin.split(':').map(Number);
|
||||||
|
return hour + Math.ceil(minute / 60);
|
||||||
|
})),
|
||||||
|
horas_totales: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
structure.horas_totales = structure.hora_máxima - structure.hora_mínima;
|
||||||
|
|
||||||
|
return structure;
|
||||||
|
},
|
||||||
|
get blocks() {
|
||||||
|
if (this.data.length === 0) return null;
|
||||||
|
return [...Array(this.structure.horas_totales).keys()].flatMap(hora => {
|
||||||
|
const baseHour = hora + this.structure.hora_mínima;
|
||||||
|
return [0, 15, 30, 45].map(block => ({ hour: baseHour, block }));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getHorarioData(hour: number, block: number, día: number) {
|
||||||
|
const foundHorario = this.data.find((horario: Horario) =>
|
||||||
|
parseInt(horario.horario_hora.split(':')[0]) === hour &&
|
||||||
|
parseInt(horario.horario_hora.split(':')[1]) === block &&
|
||||||
|
horario.horario_dia === día
|
||||||
|
);
|
||||||
|
return foundHorario;
|
||||||
|
},
|
||||||
|
isOccupied(hora: number, bloque: number, day: number) {
|
||||||
|
if (this.getHorarioData(hora, bloque, day)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const currentTimeInMinutes = hora * 60 + bloque;
|
||||||
|
|
||||||
|
for (const item of this.data) {
|
||||||
|
if (item.horario_dia !== day) {
|
||||||
|
continue; // Skip items that are not on the specified day
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the hour and minute from horario_hora
|
||||||
|
const [startHour, startMinute] = item.horario_hora.split(":").map(Number);
|
||||||
|
const startTimeInMinutes = startHour * 60 + startMinute;
|
||||||
|
|
||||||
|
// Calculate end time using duracion
|
||||||
|
const [durationHours, durationMinutes] = item.duracion.split(":").map(Number);
|
||||||
|
const endTimeInMinutes = startTimeInMinutes + (durationHours * 60) + durationMinutes;
|
||||||
|
|
||||||
|
if (currentTimeInMinutes >= startTimeInMinutes && currentTimeInMinutes < endTimeInMinutes) {
|
||||||
|
return true; // The block is occupied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // The block is not occupied by any class
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
profesores,
|
||||||
|
horarios,
|
||||||
|
mounted: async function () {
|
||||||
|
await profesores.fetch()
|
||||||
|
}
|
||||||
|
}).mount('#app')
|
||||||
@@ -1,532 +0,0 @@
|
|||||||
declare function triggerMessage(message: string, title: string, color?: string): void;
|
|
||||||
declare const write: boolean;
|
|
||||||
declare const moment: any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Funciones auxiliares
|
|
||||||
*/
|
|
||||||
type Profesor = {
|
|
||||||
id: number,
|
|
||||||
grado: string,
|
|
||||||
profesor: string,
|
|
||||||
clave: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
type Horario = {
|
|
||||||
id: number,
|
|
||||||
carrera_id: number,
|
|
||||||
materia: string,
|
|
||||||
salon: string,
|
|
||||||
profesores: Profesor[],
|
|
||||||
hora: string,
|
|
||||||
hora_final: string,
|
|
||||||
dia: string,
|
|
||||||
duracion: number,
|
|
||||||
bloques: number,
|
|
||||||
grupo: string,
|
|
||||||
materia_id: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
const compareHours = (hora1: string, hora2: string): number => {
|
|
||||||
const [h1, m1] = hora1.split(":").map(Number);
|
|
||||||
const [h2, m2] = hora2.split(":").map(Number);
|
|
||||||
|
|
||||||
if (h1 !== h2) {
|
|
||||||
return h1 > h2 ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m1 !== m2) {
|
|
||||||
return m1 > m2 ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
let horarios = [] as Horario[];
|
|
||||||
const table = document.querySelector("table") as HTMLTableElement;
|
|
||||||
if (!(table instanceof HTMLTableElement)) {
|
|
||||||
triggerMessage("No se ha encontrado la tabla", "Error", "error");
|
|
||||||
throw new Error("No se ha encontrado la tabla");
|
|
||||||
}
|
|
||||||
|
|
||||||
[...Array(16).keys()].map(x => x + 7).forEach(hora => {
|
|
||||||
// add 7 rows for each hour
|
|
||||||
[0, 15, 30, 45].map((minute: number) => `${minute}`.padStart(2, '0')).forEach((minute: string) => {
|
|
||||||
const tr = document.createElement("tr") as HTMLTableRowElement;
|
|
||||||
tr.id = `hora-${hora}:${minute}`;
|
|
||||||
tr.classList.add(hora > 13 ? "tarde" : "mañana");
|
|
||||||
if (minute == "00") {
|
|
||||||
const th = document.createElement("th") as HTMLTableCellElement;
|
|
||||||
th.classList.add("text-center");
|
|
||||||
th.scope = "row";
|
|
||||||
th.rowSpan = 4;
|
|
||||||
th.innerText = `${hora}:00`;
|
|
||||||
th.style.verticalAlign = "middle";
|
|
||||||
tr.appendChild(th);
|
|
||||||
}
|
|
||||||
|
|
||||||
["lunes", "martes", "miércoles", "jueves", "viernes", "sábado"].forEach(día => {
|
|
||||||
const td = document.createElement("td") as HTMLTableCellElement;
|
|
||||||
td.id = `hora-${hora}:${minute}-${día}`;
|
|
||||||
tr.appendChild(td);
|
|
||||||
});
|
|
||||||
const tbody = document.querySelector("tbody#horario") as HTMLTableSectionElement;
|
|
||||||
if (!(tbody instanceof HTMLTableSectionElement)) {
|
|
||||||
throw new Error("No se ha encontrado el tbody");
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody.appendChild(tr);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const empty_table = table.cloneNode(true) as HTMLTableElement;
|
|
||||||
document.querySelectorAll('.hidden').forEach((element: HTMLElement) => {
|
|
||||||
element.style.display = "none";
|
|
||||||
});
|
|
||||||
// hide the table
|
|
||||||
table.style.display = "none";
|
|
||||||
|
|
||||||
function moveHorario(id: string, día: string, hora: string) {
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
formData.append("id", id);
|
|
||||||
formData.append("hora", hora);
|
|
||||||
formData.append("día", día);
|
|
||||||
|
|
||||||
fetch("action/action_horario_update.php", {
|
|
||||||
method: "POST",
|
|
||||||
body: formData
|
|
||||||
}).then(res => res.json()).then(response => {
|
|
||||||
if (response.status == "success") {
|
|
||||||
triggerMessage("Horario movido", "Éxito", "success");
|
|
||||||
} else {
|
|
||||||
triggerMessage(response.message, "Error");
|
|
||||||
}
|
|
||||||
}).then(() => {
|
|
||||||
renderHorario();
|
|
||||||
}).catch(err => {
|
|
||||||
triggerMessage(err, "Error");
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderHorario() {
|
|
||||||
if (horarios.length == 0) {
|
|
||||||
triggerMessage("Este profesor hay horarios para mostrar", "Error", "info");
|
|
||||||
table.style.display = "none";
|
|
||||||
document.querySelectorAll('.hidden').forEach((element: HTMLElement) => element.style.display = "none");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// show the table
|
|
||||||
table.style.display = "table";
|
|
||||||
document.querySelectorAll('.hidden').forEach((element: HTMLElement) => element.style.display = "block");
|
|
||||||
// clear the table
|
|
||||||
table.innerHTML = empty_table.outerHTML;
|
|
||||||
|
|
||||||
function conflicts(horario1: Horario, horario2: Horario): boolean {
|
|
||||||
const { hora: hora_inicio1, hora_final: hora_final1, dia: dia1 } = horario1;
|
|
||||||
const { hora: hora_inicio2, hora_final: hora_final2, dia: dia2 } = horario2;
|
|
||||||
|
|
||||||
if (dia1 !== dia2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const compareInicios = compareHours(hora_inicio1, hora_inicio2);
|
|
||||||
const compareFinales = compareHours(hora_final1, hora_final2);
|
|
||||||
|
|
||||||
if (
|
|
||||||
compareInicios >= 0 && compareInicios <= compareFinales ||
|
|
||||||
compareFinales >= 0 && compareFinales <= -compareInicios
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// remove the next 5 cells
|
|
||||||
function removeNextCells(horas: number, minutos: number, dia: string, cells: number = 5) {
|
|
||||||
for (let i = 1; i <= cells; i++) {
|
|
||||||
const minute = minutos + i * 15;
|
|
||||||
const nextMinute = (minute % 60).toString().padStart(2, "0");
|
|
||||||
const nextHour = horas + Math.floor(minute / 60);
|
|
||||||
|
|
||||||
const cellId = `hora-${nextHour}:${nextMinute}-${dia}`;
|
|
||||||
const cellElement = document.getElementById(cellId);
|
|
||||||
if (cellElement) {
|
|
||||||
cellElement.remove();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(`No se ha encontrado la celda ${cellId}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function newBlock(horario: Horario, edit = false) {
|
|
||||||
function move(horario: Horario, cells: number = 5) {
|
|
||||||
const [horas, minutos] = horario.hora.split(":").map(Number);
|
|
||||||
|
|
||||||
const cell = document.getElementById(`hora-${horas}:${minutos.toString().padStart(2, "0")}-${horario.dia}`);
|
|
||||||
const { top, left } = cell.getBoundingClientRect();
|
|
||||||
|
|
||||||
const block = document.getElementById(`block-${horario.id}`);
|
|
||||||
block.style.top = `${top}px`;
|
|
||||||
block.style.left = `${left}px`;
|
|
||||||
|
|
||||||
removeNextCells(horas, minutos, horario.dia, cells);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [horas, minutos] = horario.hora.split(":").map(x => parseInt(x));
|
|
||||||
const hora = `${horas}:${minutos.toString().padStart(2, "0")}`;
|
|
||||||
horario.hora = hora;
|
|
||||||
|
|
||||||
const cell = document.getElementById(`hora-${horario.hora}-${horario.dia}`) as HTMLTableCellElement;
|
|
||||||
if (!cell) return;
|
|
||||||
|
|
||||||
cell.dataset.ids = `${horario.id}`;
|
|
||||||
|
|
||||||
const float_menu = edit ?
|
|
||||||
`<div class="menu-flotante p-2" style="opacity: .7;">
|
|
||||||
<a class="mx-2" href="#" data-toggle="modal" data-target="#modal-editar">
|
|
||||||
<i class="ing-editar ing"></i>
|
|
||||||
</a>
|
|
||||||
<a class="mx-2" href="#" data-toggle="modal" data-target="#modal-borrar">
|
|
||||||
<i class="ing-basura ing"></i>
|
|
||||||
</a>
|
|
||||||
</div>`
|
|
||||||
: '';
|
|
||||||
|
|
||||||
cell.innerHTML =
|
|
||||||
`<div style="overflow-y: auto; overflow-x: hidden; height: 100%;" id="block-${horario.id}" class="position-absolute w-100 h-100">
|
|
||||||
<small class="text-gray">${horario.hora}</small>
|
|
||||||
<b class="title">${horario.materia}</b> <br>
|
|
||||||
<br><span>Salón: </span>${horario.salon} <br>
|
|
||||||
<small class="my-2">
|
|
||||||
${horario.profesores.map((profesor: Profesor) => ` <span class="ing ing-formacion mx-1"></span>${profesor.grado ?? ''} ${profesor.profesor}`).join("<br>")}
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
${float_menu}`;
|
|
||||||
|
|
||||||
cell.classList.add("bloque-clase", "position-relative");
|
|
||||||
cell.rowSpan = horario.bloques;
|
|
||||||
// draggable
|
|
||||||
cell.draggable = write;
|
|
||||||
|
|
||||||
if (horario.bloques > 0) {
|
|
||||||
removeNextCells(horas, minutos, horario.dia, horario.bloques - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function newConflictBlock(horarios: Horario[], edit = false) {
|
|
||||||
const first_horario = horarios[0];
|
|
||||||
const [horas, minutos] = first_horario.hora.split(":").map(x => parseInt(x));
|
|
||||||
const hora = `${horas}:${minutos.toString().padStart(2, "0")}`;
|
|
||||||
const ids = horarios.map(horario => horario.id);
|
|
||||||
const cell = document.getElementById(`hora-${hora}-${first_horario.dia}`);
|
|
||||||
if (cell == null) {
|
|
||||||
console.error(`Error: No se encontró la celda: hora-${hora}-${first_horario.dia}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cell.dataset.ids = ids.join(",");
|
|
||||||
|
|
||||||
// replace the content of the cell
|
|
||||||
cell.innerHTML = `
|
|
||||||
<small class='text-danger'>
|
|
||||||
${hora}
|
|
||||||
</small>
|
|
||||||
<div class="d-flex justify-content-center align-items-center mt-4">
|
|
||||||
<div class="d-flex flex-column justify-content-center align-items-center">
|
|
||||||
<span class="ing ing-importante text-danger" style="font-size: 2rem;"></span>
|
|
||||||
<b class='text-danger'>
|
|
||||||
Empalme de ${ids.length} horarios
|
|
||||||
</b>
|
|
||||||
<hr>
|
|
||||||
<i class="text-danger">Ver horarios …</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Add classes and attributes
|
|
||||||
cell.classList.add("conflict", "bloque-clase");
|
|
||||||
cell.setAttribute("role", "button");
|
|
||||||
|
|
||||||
// Add event listener for the cell
|
|
||||||
cell.addEventListener("click", () => {
|
|
||||||
$("#modal-choose").modal("show");
|
|
||||||
const ids = cell.getAttribute("data-ids").split(",").map(x => parseInt(x));
|
|
||||||
const tbody = document.querySelector("#modal-choose tbody");
|
|
||||||
tbody.innerHTML = "";
|
|
||||||
horarios.filter(horario => ids.includes(horario.id)).sort((a, b) => compareHours(a.hora, b.hora)).forEach(horario => {
|
|
||||||
tbody.innerHTML += `
|
|
||||||
<tr data-ids="${horario.id}">
|
|
||||||
<td><small>${horario.hora.slice(0, -3)}-${horario.hora_final.slice(0, -3)}</small></td>
|
|
||||||
<td>${horario.materia}</td>
|
|
||||||
<td>
|
|
||||||
${horario.profesores.map(({ grado, profesor }) => `${grado ?? ''} ${profesor}`).join(", ")}
|
|
||||||
</td>
|
|
||||||
<td>${horario.salon}</td>
|
|
||||||
${edit ? `
|
|
||||||
<td class="text-center">
|
|
||||||
<button class="btn btn-sm btn-primary dismiss-editar" data-toggle="modal" data-target="#modal-editar">
|
|
||||||
<i class="ing-editar ing"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
<td class="text-center">
|
|
||||||
<button class="btn btn-sm btn-danger dismiss-editar" data-toggle="modal" data-target="#modal-borrar">
|
|
||||||
<i class="ing-basura ing"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
` : ""}
|
|
||||||
</tr>`;
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll(".dismiss-editar").forEach(btn => {
|
|
||||||
btn.addEventListener("click", () => $("#modal-choose").modal("hide"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function getDuration(hora_i: string, hora_f: string): number {
|
|
||||||
const [horas_i, minutos_i] = hora_i.split(":").map(x => parseInt(x));
|
|
||||||
const [horas_f, minutos_f] = hora_f.split(":").map(x => parseInt(x));
|
|
||||||
const date_i = new Date(0, 0, 0, horas_i, minutos_i);
|
|
||||||
const date_f = new Date(0, 0, 0, horas_f, minutos_f);
|
|
||||||
const diffInMilliseconds = date_f.getTime() - date_i.getTime();
|
|
||||||
const diffInMinutes = diffInMilliseconds / (1000 * 60);
|
|
||||||
const diffIn15MinuteIntervals = diffInMinutes / 15;
|
|
||||||
return Math.floor(diffIn15MinuteIntervals);
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxHoraFinal = horarios.reduce((max: Date, horario: Horario) => {
|
|
||||||
const [horas, minutos] = horario.hora_final.split(":").map(x => parseInt(x));
|
|
||||||
const date = new Date(0, 0, 0, horas, minutos);
|
|
||||||
return date > max ? date : max;
|
|
||||||
}, new Date(0, 0, 0, 0, 0));
|
|
||||||
|
|
||||||
|
|
||||||
const horaFinalMax = new Date(0, 0, 0, maxHoraFinal.getHours(), maxHoraFinal.getMinutes());
|
|
||||||
const blocks = getDuration(first_horario.hora, `${horaFinalMax.getHours()}:${horaFinalMax.getMinutes()}`);
|
|
||||||
cell.setAttribute("rowSpan", blocks.toString());
|
|
||||||
removeNextCells(horas, minutos, first_horario.dia, blocks - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const conflictBlocks = horarios.filter((horario, index, arrayHorario) =>
|
|
||||||
arrayHorario.filter((_, i) => i != index).some(horario2 =>
|
|
||||||
conflicts(horario, horario2)))
|
|
||||||
.sort((a, b) => compareHours(a.hora, b.hora));
|
|
||||||
|
|
||||||
const classes = horarios.filter(horario => !conflictBlocks.includes(horario));
|
|
||||||
|
|
||||||
const conflictBlocksPacked = []; // array of sets
|
|
||||||
conflictBlocks.forEach(horario => {
|
|
||||||
const setIndex = conflictBlocksPacked.findIndex(set => set.some(horario2 => conflicts(horario, horario2)));
|
|
||||||
if (setIndex === -1) {
|
|
||||||
conflictBlocksPacked.push([horario]);
|
|
||||||
} else {
|
|
||||||
conflictBlocksPacked[setIndex].push(horario);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
classes.forEach(horario =>
|
|
||||||
newBlock(horario, write)
|
|
||||||
)
|
|
||||||
|
|
||||||
conflictBlocksPacked.forEach(horarios =>
|
|
||||||
newConflictBlock(horarios, write)
|
|
||||||
)
|
|
||||||
|
|
||||||
// remove the elements that are not in the limits
|
|
||||||
let max_hour = Math.max(...horarios.map(horario => {
|
|
||||||
const lastMoment = moment(horario.hora, "HH:mm").add(horario.bloques * 15, "minutes");
|
|
||||||
const lastHour = moment(`${lastMoment.hours()}:00`, "HH:mm");
|
|
||||||
const hourInt = parseInt(lastMoment.format("HH"));
|
|
||||||
|
|
||||||
return lastMoment.isSame(lastHour) ? hourInt - 1 : hourInt;
|
|
||||||
}));
|
|
||||||
|
|
||||||
let min_hour = Math.min(...horarios.map(horario => parseInt(horario.hora.split(":")[0])));
|
|
||||||
|
|
||||||
document.querySelectorAll("tbody#horario tr").forEach(hora => {
|
|
||||||
const hora_id = parseInt(hora.id.split("-")[1].split(":")[0]);
|
|
||||||
(hora_id < min_hour || hora_id > max_hour) ? hora.remove() : null;
|
|
||||||
})
|
|
||||||
|
|
||||||
// if there is no sábado, remove the column
|
|
||||||
if (!horarios.some(horario => horario.dia == "sábado")) {
|
|
||||||
document.querySelectorAll("tbody#horario td").forEach(td => {
|
|
||||||
if (td.id.split("-")[2] == "sábado") {
|
|
||||||
td.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove the header (the last)
|
|
||||||
document.querySelector("#headers").lastElementChild.remove();
|
|
||||||
}
|
|
||||||
// adjust width
|
|
||||||
const ths = document.querySelectorAll("tr#headers th") as NodeListOf<HTMLTableCellElement>;
|
|
||||||
ths.forEach((th, key) =>
|
|
||||||
th.style.width = (key == 0) ? "5%" : `${95 / (ths.length - 1)}%`
|
|
||||||
);
|
|
||||||
|
|
||||||
// search item animation
|
|
||||||
const menúFlontantes = document.querySelectorAll(".menu-flotante");
|
|
||||||
menúFlontantes.forEach((element) => {
|
|
||||||
element.classList.add("d-none");
|
|
||||||
element.parentElement.addEventListener("mouseover", () =>
|
|
||||||
element.classList.remove("d-none")
|
|
||||||
);
|
|
||||||
element.parentElement.addEventListener("mouseout", (e) =>
|
|
||||||
element.classList.add("d-none")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// droppables
|
|
||||||
// forall the .bloque-elements add the event listeners for drag and drop
|
|
||||||
|
|
||||||
document.querySelectorAll(".bloque-clase").forEach(element => {
|
|
||||||
function dragStart() {
|
|
||||||
this.classList.add("dragging");
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragEnd() {
|
|
||||||
this.classList.remove("dragging");
|
|
||||||
}
|
|
||||||
|
|
||||||
element.addEventListener("dragstart", dragStart);
|
|
||||||
element.addEventListener("dragend", dragEnd);
|
|
||||||
});
|
|
||||||
|
|
||||||
// forall the cells that are not .bloque-clase add the event listeners for drag and drop
|
|
||||||
document.querySelectorAll("td:not(.bloque-clase)").forEach(element => {
|
|
||||||
function dragOver(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
this.classList.add("dragging-over");
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragLeave() {
|
|
||||||
this.classList.remove("dragging-over");
|
|
||||||
}
|
|
||||||
|
|
||||||
function drop() {
|
|
||||||
this.classList.remove("dragging-over");
|
|
||||||
const dragging = document.querySelector(".dragging");
|
|
||||||
|
|
||||||
const id = dragging.getAttribute("data-ids");
|
|
||||||
const hora = this.id.split("-")[1];
|
|
||||||
const días = ["lunes", "martes", "miércoles", "jueves", "viernes", "sábado"];
|
|
||||||
let día = this.id.split("-")[2];
|
|
||||||
día = días.indexOf(día) + 1;
|
|
||||||
|
|
||||||
// rowspan
|
|
||||||
const bloques = parseInt(dragging.getAttribute("rowspan"));
|
|
||||||
const horaMoment = moment(hora, "HH:mm");
|
|
||||||
const horaFin = horaMoment.add(bloques * 15, "minutes");
|
|
||||||
|
|
||||||
const limit = moment('22:00', 'HH:mm');
|
|
||||||
|
|
||||||
if (horaFin.isAfter(limit)) {
|
|
||||||
triggerMessage("No se puede mover el bloque a esa hora", "Error");
|
|
||||||
|
|
||||||
// scroll to the top
|
|
||||||
window.scrollTo(0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the horario
|
|
||||||
// remove the horario
|
|
||||||
const bloque = document.querySelector(`.bloque-clase[data-ids="${id}"]`) as HTMLElement;
|
|
||||||
|
|
||||||
// remove all children
|
|
||||||
while (bloque.firstChild) {
|
|
||||||
bloque.removeChild(bloque.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepend a loading child
|
|
||||||
const loading = `<div class="spinner-border" role="status" style="width: 3rem; height: 3rem;">
|
|
||||||
<span class="sr-only">Loading...</span>
|
|
||||||
</div>`;
|
|
||||||
bloque.insertAdjacentHTML("afterbegin", loading);
|
|
||||||
// add style vertical-align: middle
|
|
||||||
bloque.style.verticalAlign = "middle";
|
|
||||||
bloque.classList.add("text-center");
|
|
||||||
// remove draggable
|
|
||||||
bloque.removeAttribute("draggable");
|
|
||||||
|
|
||||||
moveHorario(id, día, hora);
|
|
||||||
}
|
|
||||||
|
|
||||||
element.addEventListener("dragover", dragOver);
|
|
||||||
element.addEventListener("dragleave", dragLeave);
|
|
||||||
element.addEventListener("drop", drop);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const form = document.getElementById('form') as HTMLFormElement;
|
|
||||||
|
|
||||||
if (!(form instanceof HTMLFormElement)) {
|
|
||||||
triggerMessage('No se ha encontrado el formulario', 'Error', 'danger');
|
|
||||||
throw new Error("No se ha encontrado el formulario");
|
|
||||||
}
|
|
||||||
|
|
||||||
form.querySelector('#clave_profesor').addEventListener('input', function (e) {
|
|
||||||
const input = form.querySelector('#clave_profesor') as HTMLInputElement;
|
|
||||||
const option = form.querySelector(`option[value="${input.value}"]`) as HTMLOptionElement;
|
|
||||||
|
|
||||||
if (input.value == "") {
|
|
||||||
input.classList.remove("is-invalid", "is-valid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!option) {
|
|
||||||
input.classList.remove("is-valid");
|
|
||||||
input.classList.add("is-invalid");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const profesor_id = form.querySelector('#profesor_id') as HTMLInputElement;
|
|
||||||
profesor_id.value = option.dataset.id;
|
|
||||||
input.classList.remove("is-invalid");
|
|
||||||
input.classList.add("is-valid");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
form.addEventListener('submit', async function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const input = form.querySelector('#clave_profesor') as HTMLInputElement;
|
|
||||||
if (input.classList.contains("is-invalid")) {
|
|
||||||
triggerMessage('El profesor no se encuentra registrado', 'Error', 'danger');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const formData = new FormData(form);
|
|
||||||
try {
|
|
||||||
const buttons = document.querySelectorAll("button") as NodeListOf<HTMLButtonElement>;
|
|
||||||
buttons.forEach(button => {
|
|
||||||
button.disabled = true;
|
|
||||||
button.classList.add("disabled");
|
|
||||||
});
|
|
||||||
const response = await fetch('action/action_horario_profesor.php', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData,
|
|
||||||
});
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
buttons.forEach(button => {
|
|
||||||
button.disabled = false;
|
|
||||||
button.classList.remove("disabled");
|
|
||||||
});
|
|
||||||
|
|
||||||
if (data.status == 'success') {
|
|
||||||
horarios = data.data;
|
|
||||||
renderHorario();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
triggerMessage(data.message, 'Error en la consulta', 'warning');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
triggerMessage('Fallo al consutar los datos ', 'Error', 'danger');
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const input = form.querySelector('#clave_profesor') as HTMLInputElement;
|
|
||||||
const option = form.querySelector(`option[value="${input.value}"]`) as HTMLOptionElement;
|
|
||||||
|
|
||||||
48
usuarios.php
48
usuarios.php
@@ -1,22 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once 'class/c_login.php';
|
require_once 'class/c_login.php';
|
||||||
require_once 'include/bd_pdo.php';
|
require_once 'include/bd_pdo.php';
|
||||||
|
|
||||||
if (!isset($_SESSION['user'])) {
|
if (!isset($_SESSION['user'])) {
|
||||||
header('Location: index.php');
|
header('Location: index.php');
|
||||||
exit;
|
exit;
|
||||||
} else
|
} else
|
||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
$user->access();
|
$user->access();
|
||||||
if (!$user->admin && $user->acceso == 'n') {
|
|
||||||
|
if ($user->acceso == null) {
|
||||||
header('Location: main.php?error=1');
|
header('Location: main.php?error=1');
|
||||||
} else {
|
} else {
|
||||||
$user->print_to_log('Usuarios');
|
$user->print_to_log('Usuarios');
|
||||||
}
|
}
|
||||||
$fac = $user->facultad['facultad_id'] ?? null;
|
$fac = $user->facultad['facultad_id'] ?? null;
|
||||||
if ($user->admin) {
|
|
||||||
$fac = null;
|
|
||||||
}
|
|
||||||
#echo $fac;
|
#echo $fac;
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@@ -86,7 +83,7 @@ if ($user->admin) {
|
|||||||
$fs_roles = $db
|
$fs_roles = $db
|
||||||
->orderBy('rol_titulo', 'asc')
|
->orderBy('rol_titulo', 'asc')
|
||||||
->get("rol");
|
->get("rol");
|
||||||
if ($user->admin) {
|
if (!$user->facultad['facultad_id']) {
|
||||||
$fs_facultades = $db
|
$fs_facultades = $db
|
||||||
->orderBy('facultad_nombre', 'asc')
|
->orderBy('facultad_nombre', 'asc')
|
||||||
->get('facultad');
|
->get('facultad');
|
||||||
@@ -178,12 +175,12 @@ if ($user->admin) {
|
|||||||
<th>Correo</th>
|
<th>Correo</th>
|
||||||
<th>Clave</th>
|
<th>Clave</th>
|
||||||
<th>Rol</th>
|
<th>Rol</th>
|
||||||
<?php if ($user->admin) { ?>
|
<? if (!$user->facultad['facultad_id']) { ?>
|
||||||
<th>Facultad</th>
|
<th>Facultad</th>
|
||||||
<?php } ?>
|
<? } ?>
|
||||||
<?php if ($user->acceso == 'w') { ?>
|
<? if ($user->acceso == 'w') { ?>
|
||||||
<th>Acciones</th>
|
<th>Acciones</th>
|
||||||
<?php } ?>
|
<? } ?>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@@ -206,19 +203,19 @@ if ($user->admin) {
|
|||||||
<td class="text-primary">
|
<td class="text-primary">
|
||||||
<?= $usuario['titulo'] ?>
|
<?= $usuario['titulo'] ?>
|
||||||
</td>
|
</td>
|
||||||
<?php if ($user->admin) { ?>
|
<? if (!$user->facultad['facultad_id']) { ?>
|
||||||
<td class="text-primary">
|
<td class="text-primary">
|
||||||
<?= $usuario['facultad_nombre'] ?>
|
<?= $usuario['facultad_nombre'] ?>
|
||||||
</td>
|
</td>
|
||||||
<?php } ?>
|
<? } ?>
|
||||||
<?php if ($user->acceso == 'w') { ?>
|
<? if ($user->acceso == 'w') { ?>
|
||||||
<td class="text-center icono-acciones">
|
<td class="text-center icono-acciones">
|
||||||
<a href="#" data-toggle="modal" data-target="#modal" data-tipo="2" title="Editar"><span
|
<a href="#" data-toggle="modal" data-target="#modal" data-tipo="2" title="Editar"><span
|
||||||
class="ing-editar ing-fw"></span></a>
|
class="ing-editar ing-fw"></span></a>
|
||||||
</td>
|
</td>
|
||||||
<?php } ?>
|
<? } ?>
|
||||||
</tr>
|
</tr>
|
||||||
<?php } ?>
|
<? } ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -291,7 +288,7 @@ if ($user->admin) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($user->admin) { ?>
|
<? if (!$user->facultad['facultad_id']) { ?>
|
||||||
<div class="form-group row" id="mdatalist">
|
<div class="form-group row" id="mdatalist">
|
||||||
<label for="dlfacultad" class="col-4 col-form-label">Facultad *</label>
|
<label for="dlfacultad" class="col-4 col-form-label">Facultad *</label>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
@@ -384,9 +381,9 @@ if ($user->admin) {
|
|||||||
var button = $(event.relatedTarget);
|
var button = $(event.relatedTarget);
|
||||||
var tipo = button.data('tipo');
|
var tipo = button.data('tipo');
|
||||||
var modal = $(this);
|
var modal = $(this);
|
||||||
setDatalistFirst('#mrol');
|
// setDatalistFirst('#mrol');
|
||||||
<?php if ($user->admin) { ?>
|
<?php if ($user->admin) { ?>
|
||||||
setDatalistFirst("#dlfacultad");
|
// setDatalistFirst("#dlfacultad");
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
$("#mnombre").removeClass("is-invalid");
|
$("#mnombre").removeClass("is-invalid");
|
||||||
$("#mclave").removeClass("is-invalid");
|
$("#mclave").removeClass("is-invalid");
|
||||||
@@ -398,7 +395,7 @@ if ($user->admin) {
|
|||||||
$('#mnombre').val("");
|
$('#mnombre').val("");
|
||||||
$('#mcorreo').val("");
|
$('#mcorreo').val("");
|
||||||
$('#id').val("");
|
$('#id').val("");
|
||||||
<?php if ($user->admin) { ?>
|
<?php if (!$user->facultad['facultad_id']) { ?>
|
||||||
$('#mfacultad').val(<?= $fac ?>);
|
$('#mfacultad').val(<?= $fac ?>);
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
}
|
}
|
||||||
@@ -422,9 +419,9 @@ if ($user->admin) {
|
|||||||
$('#mclave').val(result['usuario_clave']);
|
$('#mclave').val(result['usuario_clave']);
|
||||||
$('#mcorreo').val(result['usuario_correo']);
|
$('#mcorreo').val(result['usuario_correo']);
|
||||||
setDatalist('#mrol', result['rol_id']);
|
setDatalist('#mrol', result['rol_id']);
|
||||||
<?php if ($user->admin) { ?>
|
<? if (!$user->facultad['facultad_id']) { ?>
|
||||||
setDatalist('#dlfacultad', result['facultad_id']);
|
setDatalist('#dlfacultad', result['facultad_id']);
|
||||||
<?php } ?>
|
<? } ?>
|
||||||
},
|
},
|
||||||
error: function () {
|
error: function () {
|
||||||
console.log("Error")
|
console.log("Error")
|
||||||
@@ -441,18 +438,13 @@ if ($user->admin) {
|
|||||||
$('#desc-error').html("No puede tener espacios al inicio");
|
$('#desc-error').html("No puede tener espacios al inicio");
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
if (error) {
|
return !error;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).on("click", ".btn-reset", function (event) {
|
$(document).on("click", ".btn-reset", function (event) {
|
||||||
var forma = $(this).parents("form");
|
var forma = $(this).parents("form");
|
||||||
forma.find("input[type=text]").val("");
|
forma.find("input[type=text]").val("");
|
||||||
setDatalistFirst("#filter_rol");
|
// setDatalistFirst("#filter_rol");
|
||||||
forma.submit();
|
forma.submit();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user']))
|
|||||||
$user = unserialize($_SESSION['user']);
|
$user = unserialize($_SESSION['user']);
|
||||||
|
|
||||||
$user->access('reporte_de_asistencias');
|
$user->access('reporte_de_asistencias');
|
||||||
if ( !$user->admin && $user->acceso == 'n' )
|
if ( $user->acceso == null )
|
||||||
die(header('Location: main.php?error=1'));
|
die(header('Location: main.php?error=1'));
|
||||||
|
|
||||||
$user->print_to_log('Consultar: Reporte de asistencias de profesor');
|
$user->print_to_log('Consultar: Reporte de asistencias de profesor');
|
||||||
|
|||||||
Reference in New Issue
Block a user