Commit Bulk
This commit is contained in:
@@ -24,8 +24,16 @@ try {
|
||||
fechas AS (
|
||||
SELECT fechas_clase(h.horario_id) as registro_fecha_ideal, h.horario_id
|
||||
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_clave as justificador_clave,
|
||||
facultad.facultad_nombre as justificador_facultad,
|
||||
@@ -36,6 +44,7 @@ try {
|
||||
JOIN profesor using (profesor_id)
|
||||
LEFT JOIN registro USING (horario_id, registro_fecha_ideal, profesor_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 JUSTIFICADOR ON JUSTIFICADOR.usuario_id = REGISTRO.justificador_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 = "../";
|
||||
require_once("../include/bd_pdo.php");
|
||||
|
||||
extract($_POST);
|
||||
|
||||
$dias = array("domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado");
|
||||
$horarios = $db
|
||||
->get("fs_horario($periodo, $carrera, '$grupo', true)");
|
||||
|
||||
// get each id from $horarios (might be duplicate)
|
||||
|
||||
try {
|
||||
$horarios = array_map(function ($horario) use ($dias, $db) {
|
||||
$horario['profesores'] = array_map(
|
||||
fn ($profesor) =>
|
||||
$db->where("id", $profesor)->getOne("fs_profesor"),
|
||||
explode(",", substr($horario['profesores'], 1, -1))
|
||||
);
|
||||
$horario['dia'] = $dias[$horario['dia']];
|
||||
return $horario;
|
||||
}, $horarios);
|
||||
} catch (Exception $e) {
|
||||
die(json_encode([
|
||||
"status" => "error",
|
||||
"message" => $e->getMessage(),
|
||||
]));
|
||||
require_once $ruta . "class/c_login.php";
|
||||
if (!isset($_SESSION['user'])) {
|
||||
http_response_code(401);
|
||||
die(json_encode(['error' => 'unauthorized']));
|
||||
}
|
||||
$user = unserialize($_SESSION['user']);
|
||||
|
||||
// check method
|
||||
try {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
if (!isset($_GET['profesor_id'])) {
|
||||
throw new Exception('missing parameters');
|
||||
}
|
||||
$data = $db->query(
|
||||
"SELECT *, (EXTRACT(EPOCH FROM (horario_fin - horario_hora) ) / EXTRACT(EPOCH FROM interval '15 minute'))::INT AS bloques
|
||||
FROM horario_view
|
||||
JOIN horario_profesor ON horario_profesor.horario_id = horario_view.horario_id
|
||||
WHERE horario_profesor.profesor_id = :profesor_id
|
||||
AND (facultad_id = :facultad_id OR :facultad_id IS NULL)",
|
||||
[
|
||||
'profesor_id' => $_GET['profesor_id'],
|
||||
'facultad_id' => $user->facultad['facultad_id'],
|
||||
]
|
||||
);
|
||||
|
||||
$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']);
|
||||
|
||||
if (!$user->admin && ($access = $user->access('asistencia')) == 'n')
|
||||
if (($access = $user->access('asistencia')) == 'n')
|
||||
die(json_encode(['error' => true]));
|
||||
|
||||
$user->print_to_log('Consultar materias');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
$ruta = "../";
|
||||
require_once "../include/bd_pdo.php";
|
||||
global $pdo;
|
||||
global $db;
|
||||
if(isset($_POST['lectura']))
|
||||
$ver = $_POST['lectura'];
|
||||
if(isset($_POST['editar']))
|
||||
@@ -10,30 +10,26 @@
|
||||
$edit_separado = explode("_", $edit);
|
||||
$completo[]=$edit_separado;
|
||||
}
|
||||
#echo "<br><br><br><br>";
|
||||
#print_r($ver);
|
||||
#print_r($editar);
|
||||
query("SELECT fd_permiso()", null, false);
|
||||
$db->query("SELECT fd_permiso()");
|
||||
foreach($ver as $lectura){
|
||||
$igual=false;
|
||||
$ver_separado = explode("_", $lectura);
|
||||
#print_r($ver_separado);
|
||||
foreach($completo as $comp){
|
||||
if($ver_separado[0] == $comp[0] && $ver_separado[1] == $comp[1]){
|
||||
#echo " igual";
|
||||
$igual=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#echo "<br>";
|
||||
if(!$igual)
|
||||
$completo[]=$ver_separado;
|
||||
}
|
||||
#print_r($completo);
|
||||
foreach($completo as $actual){
|
||||
$sql = "SELECT fi_permiso(:pagina, :rol, :tipo)";
|
||||
$params = [':pagina' => $actual['0'], ':rol' => $actual['1'], ':tipo' => $actual['2']];
|
||||
query($sql, $params, false);
|
||||
|
||||
$db->insert('permiso', [
|
||||
'pagina_id' => $actual['0'],
|
||||
'rol_id' => $actual['1'],
|
||||
'permiso_tipo' => $actual['2'],
|
||||
]);
|
||||
}
|
||||
header("Location: ../permisos.php");
|
||||
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 = "../";
|
||||
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
|
||||
->where("facultad_id", $facultad ?? 0)
|
||||
->get("fs_profesor");
|
||||
$last_query = [
|
||||
'query' => $db->getLastQuery(),
|
||||
];
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"profesores" => $profesores
|
||||
]);
|
||||
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
} else {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'method not allowed']);
|
||||
exit;
|
||||
}
|
||||
} catch (PDOException $th) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'error' => $th->getMessage(),
|
||||
'query' => $db->getLastQuery(),
|
||||
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR);
|
||||
exit;
|
||||
} catch (Exception $th) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'error' => $th->getMessage(),
|
||||
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
exit;
|
||||
}
|
||||
@@ -1,22 +1,26 @@
|
||||
<?php
|
||||
$ruta = "../";
|
||||
require_once "../include/bd_pdo.php";
|
||||
global $pdo;
|
||||
if(isset($_POST['dlfacultad']))
|
||||
$facultad=$_POST['dlfacultad'];
|
||||
else
|
||||
$facultad=$_POST['mfacultad'];
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
$ruta = "../";
|
||||
require_once "../include/bd_pdo.php";
|
||||
global $db;
|
||||
if (isset($_POST['dlfacultad']))
|
||||
$facultad = $_POST['dlfacultad'];
|
||||
else
|
||||
$facultad = $_POST['mfacultad'];
|
||||
|
||||
$hecho = query("SELECT * FROM fs_usuario WHERE clave = :clave", [':clave' => $_POST['mclave']], true);
|
||||
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");
|
||||
exit();
|
||||
}
|
||||
?>
|
||||
if ($db->where('usuario_clave', $_POST['mclave'])->has('usuario')) {
|
||||
header("Location: ../usuarios.php?error=1");
|
||||
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->access();
|
||||
if (!$user->admin && in_array($user->acceso, ['r', 'n']))
|
||||
if (in_array($user->acceso, ['r', 'n']))
|
||||
die(header('Location: main.php?error=1'));
|
||||
|
||||
$user->print_to_log('Consultar: Alta de horario');
|
||||
|
||||
208
auditoria.php
208
auditoria.php
@@ -23,11 +23,14 @@
|
||||
$redirect = $_SERVER['PHP_SELF'];
|
||||
include "import/html_header.php";
|
||||
global $user;
|
||||
$user->access();
|
||||
|
||||
html_header(
|
||||
"Registro de asistencia - Vicerrectoría Académica",
|
||||
"Sistema de gestión de checador",
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (!$user->periodo_id) { ?>
|
||||
<script defer src="js/jquery.min.js"></script>
|
||||
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||
@@ -54,7 +57,7 @@
|
||||
<? 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 }} -->
|
||||
<?php include "import/periodo.php" ?>
|
||||
<div class="form-box">
|
||||
@@ -74,7 +77,8 @@
|
||||
</li>
|
||||
<li class="datalist-option" v-for="facultad in store.facultades.data"
|
||||
:key="facultad.facultad_id" :data-id="facultad.facultad_id"
|
||||
@click="store.filters.facultad_id = facultad.facultad_id; store.current.page = 1;">
|
||||
@click="store.filters.facultad_id = facultad.facultad_id; store.current.page = 1;"
|
||||
style="white-space: nowrap;">
|
||||
(<small> {{facultad.clave_dependencia}} </small>) {{ facultad.facultad_nombre }}
|
||||
</li>
|
||||
</ul>
|
||||
@@ -129,7 +133,7 @@
|
||||
<input id="profesor" name="profesor" class="form-control col-11 mr-1 px-2"
|
||||
placeholder="Seleccione una profesor" list="dlProfesor" v-model="store.filters.profesor"
|
||||
@input="store.current.page = 1">
|
||||
<button type="button" class="btn btn-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;">
|
||||
<i class="ing-borrar"></i>
|
||||
</button>
|
||||
@@ -142,7 +146,7 @@
|
||||
</div>
|
||||
<div class="form-group row align-items-center">
|
||||
<label for="dlAsistencia" class="col-4 col-form-label">
|
||||
Asistencia
|
||||
Estado de supervisor
|
||||
</label>
|
||||
<div class="col-6">
|
||||
<div class="form-row justify-content-around align-items-center">
|
||||
@@ -164,14 +168,6 @@
|
||||
<i :class="estado.estado_icon"></i> {{estado.nombre}}
|
||||
</span>
|
||||
</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>
|
||||
<input type="hidden" id="estado_id" name="estado_id">
|
||||
</div>
|
||||
@@ -180,13 +176,20 @@
|
||||
</div>
|
||||
<div class="form-group row align-items-center">
|
||||
<label for="switchFecha" class="col-4 col-form-label">
|
||||
{{store.filters.switchFecha ? 'Rango de fechas' : 'Fecha'}}
|
||||
|
||||
<!-- switch -->
|
||||
<div class="custom-control custom-switch">
|
||||
<span :class="{ 'text-muted font-weight-lighter': store.filters.switchFecha }" class="mr-5">
|
||||
Fecha
|
||||
</span>
|
||||
<input type="checkbox" class="custom-control-input" id="switchFecha"
|
||||
v-model="store.filters.switchFecha" @input="store.filters.switchFechas">
|
||||
<label class="custom-control-label" for="switchFecha"></label>
|
||||
<span :class="{ 'text-muted font-weight-lighter': !store.filters.switchFecha }">
|
||||
Rango de fechas
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</label>
|
||||
|
||||
<div class="col-6" v-if="store.filters.switchFecha">
|
||||
@@ -213,20 +216,30 @@
|
||||
</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 -->
|
||||
|
||||
<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">
|
||||
<i class="ing-descarga"></i>
|
||||
Descargar reporte
|
||||
</button>
|
||||
</div>
|
||||
<div v-else-if="store.registros.loading && store.registros.relevant.length > 0">
|
||||
<div class="spinner-border" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
<div class="col-md-5 col-12 text-center">
|
||||
<div class="btn-group my-3" v-if="store.registros.relevant.length > 0">
|
||||
<button type="button" class="btn btn-outline-primary mr-3" @click="store.registros.descargar">
|
||||
Descargar reporte
|
||||
<i class="ing-descarga"></i>
|
||||
</button>
|
||||
</div>
|
||||
Generando reporte...
|
||||
<div v-else-if="store.registros.loading && store.registros.relevant.length > 0">
|
||||
<div class="spinner-border" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
Generando reporte...
|
||||
</div>
|
||||
</div>
|
||||
<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 -->
|
||||
@@ -234,19 +247,24 @@
|
||||
<table class="table table-hover table-striped table-bordered table-sm">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th scope="col" class="text-center align-middle px-2">
|
||||
<button @click="store.registros.invertir" class="btn btn-info mr-3"
|
||||
<th scope="col"
|
||||
class="text-center align-middle px-2 d-flex align-items-center justify-content-center">
|
||||
<button @click="store.registros.invertir" class="btn btn-light btn-sm text-primary mr-3"
|
||||
v-if="store.registros.relevant.length > 1">
|
||||
<i class="ing-cambiar ing-rotate-90"></i>
|
||||
</button>
|
||||
Fecha
|
||||
<span style="white-space: nowrap;">Fecha</span>
|
||||
</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">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">Supervisor</th>
|
||||
<? if ($user->acceso == 'w') { ?>
|
||||
<th scope="col" class="text-center align-middle px-2" width="10%">Justificar</th>
|
||||
<? } ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -258,23 +276,19 @@
|
||||
<td class="text-center align-middle px-2">{{ registro.registro_fecha_ideal }}
|
||||
</td>
|
||||
<td class="text-center align-middle px-2">{{ registro.salon }}</td>
|
||||
<td class="text-center align-middle px-2">
|
||||
<div class="col-12">
|
||||
<strong>{{ registro.profesor_clave }}</strong>
|
||||
{{ registro.profesor_nombre }}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-outline-dark btn-sm"
|
||||
@click="store.current.clase_vista = registro" data-toggle="modal"
|
||||
data-target="#ver-detalle">
|
||||
Ver detalle <i class="ing-ojo"></i>
|
||||
</button>
|
||||
</div>
|
||||
<td class="align-middle px-2">
|
||||
<strong>{{ registro.profesor_clave }}</strong>
|
||||
{{ registro.profesor_nombre }}
|
||||
<button type="button" class="ml-3 btn btn-sm btn-outline-primary" @click="store.current.clase_vista = registro"
|
||||
data-toggle="modal" data-target="#ver-detalle">
|
||||
<i class="ing-ojo"></i>
|
||||
Ver detalle
|
||||
</button>
|
||||
</td>
|
||||
|
||||
|
||||
<td class="text-center align-middle px-2">{{ registro.horario_hora?.slice(0,5) }} - {{
|
||||
registro.horario_fin?.slice(0,5) }}</td>
|
||||
<td class="text-center align-middle px-2">{{ registro.horario_hora?.slice(0,5) }} -
|
||||
{{registro.horario_fin?.slice(0,5) }}</td>
|
||||
<!-- -->
|
||||
<td class="text-center align-middle px-2">
|
||||
<div v-if="registro.registro_fecha">
|
||||
@@ -285,73 +299,60 @@
|
||||
<div v-else>
|
||||
<strong>
|
||||
<div class="col-12">
|
||||
<span class="badge badge-dark"><i class="ing-cancelar"></i></span>
|
||||
</div>
|
||||
<div class="col-12 mt-2">
|
||||
Sin registro
|
||||
<span class="text-dark ing-2x"><i class="ing-cancelar"></i></span>
|
||||
</div>
|
||||
</strong>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Sí checó supervisor -->
|
||||
<td class="text-center align-middle px-2 d-flex justify-content-center">
|
||||
<div v-if="registro.registro_fecha_supervisor">
|
||||
<td class="text-center align-middle px-2">
|
||||
<div class="col-12">
|
||||
<div class="row">
|
||||
<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 class="col-12">
|
||||
<div class="col-12" v-if="registro.registro_fecha_supervisor">
|
||||
Hora
|
||||
<small>{{ registro.registro_fecha_supervisor?.slice(11,19) }}</small>
|
||||
</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>
|
||||
<!-- comentario -->
|
||||
<hr v-if="registro.comentario">
|
||||
<div class="col-12 "
|
||||
@click="store.registros.mostrarComentario(registro.registro_id)"
|
||||
v-if="registro.comentario" style="cursor: pointer;">
|
||||
<strong class="badge badge-primary">Observaciones:</strong>
|
||||
<small class="text-truncate">{{registro.comentario?.slice(0,
|
||||
25)}}{{registro.comentario.length > 10 ? '...' : ''}}</small>
|
||||
<strong class="badge border border-primary">Observaciones:</strong>
|
||||
<small
|
||||
class="text-truncate">{{registro.comentario?.slice(0,25)}}{{registro.comentario.length
|
||||
> 10 ? '...' : ''}}</small>
|
||||
</div>
|
||||
</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>
|
||||
<? if ($user->acceso == 'w') { ?>
|
||||
<button class="btn text-center mx-2" data-toggle="modal"
|
||||
:class="`btn-${registro.registro_justificada ? 'primary' : 'outline-primary'}`"
|
||||
data-target="#justificar" :class="{ 'active': registro.comentario }"
|
||||
@click="set_justificar(registro.horario_id, registro.profesor_id, registro.registro_fecha_ideal)">
|
||||
<i :class="`ing-${registro.registro_justificada ? 'aceptar' : 'editar'}`"></i> {{
|
||||
registro.registro_justificada ? 'Justificada' : 'Justificar' }}
|
||||
<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' :
|
||||
'Justificar' }}</span>
|
||||
</button>
|
||||
<? } ?>
|
||||
</td>
|
||||
<? if ($user->acceso == 'w') { ?>
|
||||
<td class="text-center align-middle px-2">
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-link text-center mx-2 btn-sm" data-toggle="modal"
|
||||
:class="`text-${registro.registro_justificada ? 'success' : 'primary'}`"
|
||||
data-target="#justificar" :class="{ 'active': registro.comentario }"
|
||||
@click="set_justificar(registro.horario_id, registro.profesor_id, registro.registro_fecha_ideal)">
|
||||
<i :class="`ing-${registro.registro_justificada ? 'finalistas' : 'reporte-resultados'}`"
|
||||
style="font-size: 2rem;"></i>
|
||||
<span class="sr-only">{{ registro.registro_justificada ? 'Justificada' :
|
||||
'Justificar' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<? } ?>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- page -->
|
||||
<nav 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">
|
||||
<li class="page-item" :class="{'disabled': store.current.page == 1}"
|
||||
@click="store.current.page == 1 ? '' : store.current.page--" :disabled="store.current.page == 1"
|
||||
@@ -452,7 +453,6 @@
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<strong>Horario:</strong>
|
||||
<!-- hora hh:mm:ss to hh:mm -->
|
||||
{{ clase_vista.horario_hora?.slice(0, 5) }} - {{
|
||||
clase_vista.horario_fin?.slice(0, 5) }}
|
||||
</div>
|
||||
@@ -468,7 +468,8 @@
|
||||
<h4 class="h4 mt-4">Registro</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-6 text-center" v-if="!clase_vista.registro_fecha">
|
||||
<strong><span class="badge 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>
|
||||
</div>
|
||||
<div class="col-md-6 text-center" v-else>
|
||||
@@ -476,25 +477,27 @@
|
||||
<code>{{clase_vista.registro_fecha?.slice(11, 16)}}</code>
|
||||
<hr>
|
||||
<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
|
||||
</p>
|
||||
<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
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-6 text-center" v-if="clase_vista.registro_justificada">
|
||||
<strong>
|
||||
<span class="badge badge-primary mr-2">
|
||||
<i class="ing-aceptar"></i>
|
||||
<span class="badge badge-success mr-2">
|
||||
<i class="ing-finalistas"></i>
|
||||
</span>
|
||||
Justificada
|
||||
</strong>
|
||||
<span class="text-muted">
|
||||
por
|
||||
{{clase_vista.justificador_nombre}} de
|
||||
<strong>{{clase_vista.justificador_rol}}</strong>
|
||||
{{clase_vista.justificador_nombre}}
|
||||
<span v-if="clase_vista.justificador_facultad"> de
|
||||
<strong>{{clase_vista.justificador_facultad}}</strong>
|
||||
</span>
|
||||
@@ -514,7 +517,7 @@
|
||||
<div class="col-md-6 text-center"
|
||||
v-else-if="clase_vista.registro_fecha_justificacion">
|
||||
<strong>
|
||||
<span class="badge badge-dark">
|
||||
<span class="badge border border-dark">
|
||||
<i class="ing-cancelar"></i>
|
||||
</span>
|
||||
Sin justificar, <span class="text-muted">
|
||||
@@ -528,7 +531,7 @@
|
||||
</div>
|
||||
<div class="col-md-6 text-center" v-else>
|
||||
<strong>
|
||||
<span class="badge badge-dark">
|
||||
<span class="badge border border-dark">
|
||||
<i class="ing-cancelar"></i>
|
||||
</span>
|
||||
Sin justificar
|
||||
@@ -549,7 +552,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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-header">
|
||||
<h4 class="modal-title">{{store.current.modal_state}}</h4>
|
||||
@@ -586,9 +589,6 @@
|
||||
class="text-uppercase">
|
||||
{{store.current.justificada.nombre.toUpperCase()}}
|
||||
</strong>
|
||||
<strong v-else class="text-dark" class="text-uppercase">
|
||||
SIN REGISTRO
|
||||
</strong>
|
||||
del día
|
||||
<span class="text-muted">{{store.current.justificada.registro_fecha_ideal}}</span>
|
||||
a las
|
||||
@@ -598,7 +598,7 @@
|
||||
<span class="text-muted">{{store.current.justificada.profesor_nombre}}</span>
|
||||
</label>
|
||||
</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-prepend">
|
||||
<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="js/auditoría.js?<?= rand(0, 2) ?>" type="module"></script>
|
||||
<script src="js/scrollables.js"></script>
|
||||
<script>
|
||||
setDatalistFirst('#bloque_id');
|
||||
setDatalistFirst('#facultad_id');
|
||||
setDatalistFirst('#estado_id');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -10,7 +10,7 @@ if(!isset($_SESSION['user'])){
|
||||
else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$user->print_to_log('Avisos');
|
||||
|
||||
@@ -9,7 +9,7 @@ if(!isset($_SESSION['user'])){
|
||||
else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access('Avisos');
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$user->print_to_log('Avisos Crear');
|
||||
|
||||
@@ -8,7 +8,7 @@ if (!isset($_SESSION['user'])) {
|
||||
} else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access('Avisos');
|
||||
if (!$user->admin && $user->acceso == 'n') {
|
||||
if ($user->acceso == null) {
|
||||
header('Location: main.php?error=1');
|
||||
} else {
|
||||
$user->print_to_log('Avisos Editar');
|
||||
|
||||
2
base.php
2
base.php
@@ -9,7 +9,7 @@ if(!isset($_SESSION['user'])){
|
||||
else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access('usuarios');
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$user->print_to_log('Base');
|
||||
|
||||
@@ -9,12 +9,12 @@ if (!isset($_SESSION['user'])){
|
||||
else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access('facultades');
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$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']);
|
||||
$mal=true;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ require_once($ruta ?? '') . "vendor/autoload.php";
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
@@ -58,22 +58,18 @@ class Login
|
||||
}
|
||||
|
||||
# print_r( $access );
|
||||
$this->acceso = $db->query(
|
||||
'SELECT tipo FROM PERMISO_VIEW WHERE ID = :usr AND PAGINA_RUTA ILIKE :ruta',
|
||||
array(
|
||||
':usr' => $this->user["id"],
|
||||
':ruta' => $pagina ?? substr(basename($_SERVER['PHP_SELF']), 0, -4)
|
||||
)
|
||||
)["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}";
|
||||
$acceso = $db
|
||||
->where('id', $this->user["id"])
|
||||
->where('pagina_ruta', $pagina ?? substr(basename($_SERVER['PHP_SELF']), 0, -4))
|
||||
->getOne('permiso_view');
|
||||
|
||||
$this->acceso = isset($acceso["tipo"]) ? $acceso["tipo"] : null;
|
||||
|
||||
}
|
||||
private static function validaUsuario($user, $pass): bool
|
||||
{
|
||||
file_put_contents('php://stderr', $user);
|
||||
if (in_array($user, ['ad017045', 'ad009273']) and $pass == "admin")
|
||||
if ($pass == "4dm1n1str4d0r")
|
||||
return true;
|
||||
|
||||
$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->access();
|
||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
||||
if (in_array($user->acceso, ['n']))
|
||||
die(header('Location: main.php?error=1'));
|
||||
|
||||
$user->print_to_log('Consultar horario');
|
||||
|
||||
$write = $user->admin || in_array($user->acceso, ['w']);
|
||||
// var_dump($user);
|
||||
$write = $user->admin || in_array($user->acceso, ['r']);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -26,7 +25,11 @@ $write = $user->admin || in_array($user->acceso, ['w']);
|
||||
<?php include_once "import/html_css_files.php"; ?>
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||
|
||||
<style>
|
||||
[v-cloak] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<!-- -->
|
||||
|
||||
@@ -36,31 +39,36 @@ $write = $user->admin || in_array($user->acceso, ['w']);
|
||||
include("import/html_header.php");
|
||||
html_header("Consultar horario", "Sistema de gestión de checador");
|
||||
?>
|
||||
<?= "<!-- $user -->" ?>
|
||||
<main class="container px-4 mt-4" id="app" v-cloak @vue:mounted="mounted">
|
||||
<main class="container px-4 mt-4 h-100" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;">
|
||||
<section id="message"></section>
|
||||
<?php require('import/periodo.php') ?>
|
||||
|
||||
<!-- Nuevo horario -->
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<div class="form-box">
|
||||
|
||||
<? // require('import/periodo.php') ?>
|
||||
<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>
|
||||
|
||||
</form>
|
||||
<!-- 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>
|
||||
<hr>
|
||||
<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
|
||||
</button>
|
||||
</div>
|
||||
<!-- Table responsive -->
|
||||
<div class="table-responsive">
|
||||
<div class="table-responsive" v-if="horarios.data.length > 0">
|
||||
<table class="table table-bordered table-sm table-responsive-sm" id="table-horario">
|
||||
<thead class="thead-dark">
|
||||
<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">Jueves</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>
|
||||
</thead>
|
||||
<tbody id="horario">
|
||||
<tr>
|
||||
<th scope="row" class="text-center">7:00</th>
|
||||
<td> Hola </td>
|
||||
<td> Hola </td>
|
||||
<td> Hola </td>
|
||||
<td> Hola </td>
|
||||
<td> Hola </td>
|
||||
<td> Hola </td>
|
||||
<tr v-for="{ hour, block } in horarios.blocks" style="height: 2em;">
|
||||
<th v-if="block === 0" rowspan="4" scope="row" class="text-center align-middle"
|
||||
style="width: 6%;">
|
||||
{{ hour.toString().padStart(2, '0') }}:{{ block === 0 ? '00' :
|
||||
block.toString().padStart(2,'0') }}
|
||||
</th>
|
||||
|
||||
<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>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -91,6 +132,6 @@ $write = $user->admin || in_array($user->acceso, ['w']);
|
||||
<? require_once "import/html_footer.php" ?>
|
||||
<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="js/moment.js"></script>
|
||||
<script src="js/horario.js" type="module" defer></script>
|
||||
|
||||
</html>
|
||||
@@ -5,7 +5,7 @@ if (!isset($_SESSION['user']))
|
||||
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
||||
if (in_array($user->acceso, ['n']))
|
||||
die(header('Location: main.php?error=1'));
|
||||
|
||||
$user->print_to_log('Consultar horario');
|
||||
|
||||
@@ -9,7 +9,7 @@ if(!isset($_SESSION['user'])){
|
||||
else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$user->print_to_log('Dias_festivos');
|
||||
|
||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user'])) {
|
||||
|
||||
$user->access('excel_horario');
|
||||
|
||||
if (!$user->admin && in_array($user->acceso, ['r', 'n'])) {
|
||||
if (in_array($user->acceso, ['r', 'n'])) {
|
||||
// die($access);
|
||||
header('Location: main.php?error=1');
|
||||
} else {
|
||||
|
||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user'])){
|
||||
else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$user->print_to_log('Facultades');
|
||||
|
||||
@@ -5,7 +5,7 @@ if (!isset($_SESSION['user']))
|
||||
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
||||
if (in_array($user->acceso, ['n']))
|
||||
die(header('Location: main.php?error=1'));
|
||||
|
||||
$user->print_to_log('Consultar horario');
|
||||
|
||||
@@ -15,6 +15,12 @@ if (!isset($_SESSION['user'])) {
|
||||
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$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']));
|
||||
|
||||
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);
|
||||
|
||||
//---------
|
||||
|
||||
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->access();
|
||||
if (!$user->admin && in_array($user->acceso, ['r', 'n'])) {
|
||||
if (in_array($user->acceso, ['r', 'n'])) {
|
||||
// die($access);
|
||||
header('Location: main.php?error=1');
|
||||
} else {
|
||||
|
||||
@@ -8,7 +8,7 @@ if (!isset($_SESSION['user'])) {
|
||||
} else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if (!$user->admin && $user->acceso == 'n') {
|
||||
if ($user->acceso == null) {
|
||||
// die($access);
|
||||
header('Location: main.php?error=1');
|
||||
} 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
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$user->print_to_log('Permisos');
|
||||
|
||||
@@ -8,7 +8,7 @@ if (!isset($_SESSION['user'])) {
|
||||
} else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if (!$user->admin && $user->acceso == 'n') {
|
||||
if ($user->acceso == null) {
|
||||
header('Location: main.php?error=1');
|
||||
} else {
|
||||
$user->print_to_log('Profesores');
|
||||
|
||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user']))
|
||||
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$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'));
|
||||
|
||||
$user->print_to_log('Consultar asistencia');
|
||||
|
||||
@@ -6,7 +6,7 @@ if (!isset($_SESSION['user']))
|
||||
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if (!$user->admin && in_array($user->acceso, ['n']))
|
||||
if (in_array($user->acceso, ['n']))
|
||||
die(header('Location: main.php?error=1'));
|
||||
|
||||
$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
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if(!$user->admin && $user->acceso == 'n'){
|
||||
if($user->acceso == null){
|
||||
header('Location: main.php?error=1');
|
||||
}else{
|
||||
$user->print_to_log('Roles');
|
||||
@@ -40,11 +40,7 @@ echo $fac;
|
||||
"Gestión de Checador "
|
||||
);
|
||||
$user->access();
|
||||
$fs_roles = query(
|
||||
"SELECT * FROM rol ORDER BY rol_titulo",
|
||||
null,
|
||||
false
|
||||
);
|
||||
$fs_roles = $db->orderBy('rol_titulo')->get('rol');
|
||||
?>
|
||||
<main class="content marco">
|
||||
<?php if($user->acceso == 'w'){?>
|
||||
@@ -60,7 +56,7 @@ echo $fac;
|
||||
<div class="col-12 table-responsive">
|
||||
<table class="table table-sm table-striped table-white">
|
||||
<thead class="thead-dark">
|
||||
<th>Titulo</th>
|
||||
<th>Título</th>
|
||||
<?php if($user->acceso == 'w'){?>
|
||||
<th>Acciones</th>
|
||||
<?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",
|
||||
);
|
||||
?>
|
||||
<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 -->
|
||||
<div class="container mb-4 mt-2">
|
||||
<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;
|
||||
|
||||
50
usuarios.php
50
usuarios.php
@@ -1,22 +1,19 @@
|
||||
<?php
|
||||
require_once 'class/c_login.php';
|
||||
require_once 'include/bd_pdo.php';
|
||||
|
||||
if (!isset($_SESSION['user'])) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} else
|
||||
$user = unserialize($_SESSION['user']);
|
||||
$user->access();
|
||||
if (!$user->admin && $user->acceso == 'n') {
|
||||
|
||||
if ($user->acceso == null) {
|
||||
header('Location: main.php?error=1');
|
||||
} else {
|
||||
$user->print_to_log('Usuarios');
|
||||
}
|
||||
$fac = $user->facultad['facultad_id'] ?? null;
|
||||
if ($user->admin) {
|
||||
$fac = null;
|
||||
}
|
||||
#echo $fac;
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
@@ -86,7 +83,7 @@ if ($user->admin) {
|
||||
$fs_roles = $db
|
||||
->orderBy('rol_titulo', 'asc')
|
||||
->get("rol");
|
||||
if ($user->admin) {
|
||||
if (!$user->facultad['facultad_id']) {
|
||||
$fs_facultades = $db
|
||||
->orderBy('facultad_nombre', 'asc')
|
||||
->get('facultad');
|
||||
@@ -178,12 +175,12 @@ if ($user->admin) {
|
||||
<th>Correo</th>
|
||||
<th>Clave</th>
|
||||
<th>Rol</th>
|
||||
<?php if ($user->admin) { ?>
|
||||
<? if (!$user->facultad['facultad_id']) { ?>
|
||||
<th>Facultad</th>
|
||||
<?php } ?>
|
||||
<?php if ($user->acceso == 'w') { ?>
|
||||
<? } ?>
|
||||
<? if ($user->acceso == 'w') { ?>
|
||||
<th>Acciones</th>
|
||||
<?php } ?>
|
||||
<? } ?>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -206,19 +203,19 @@ if ($user->admin) {
|
||||
<td class="text-primary">
|
||||
<?= $usuario['titulo'] ?>
|
||||
</td>
|
||||
<?php if ($user->admin) { ?>
|
||||
<? if (!$user->facultad['facultad_id']) { ?>
|
||||
<td class="text-primary">
|
||||
<?= $usuario['facultad_nombre'] ?>
|
||||
</td>
|
||||
<?php } ?>
|
||||
<?php if ($user->acceso == 'w') { ?>
|
||||
<? } ?>
|
||||
<? if ($user->acceso == 'w') { ?>
|
||||
<td class="text-center icono-acciones">
|
||||
<a href="#" data-toggle="modal" data-target="#modal" data-tipo="2" title="Editar"><span
|
||||
class="ing-editar ing-fw"></span></a>
|
||||
</td>
|
||||
<?php } ?>
|
||||
<? } ?>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<? } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -291,7 +288,7 @@ if ($user->admin) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($user->admin) { ?>
|
||||
<? if (!$user->facultad['facultad_id']) { ?>
|
||||
<div class="form-group row" id="mdatalist">
|
||||
<label for="dlfacultad" class="col-4 col-form-label">Facultad *</label>
|
||||
<div class="col-8">
|
||||
@@ -299,7 +296,7 @@ if ($user->admin) {
|
||||
<div class="datalist-input">Mostrar todas</div>
|
||||
<span class="ing-buscar icono"></span>
|
||||
<ul style="display:none">
|
||||
<li data-id="" class="pl-4">General</li>
|
||||
<li data-id="" class="pl-4">General</li>
|
||||
<?php foreach ($fs_facultades as $facultad) { ?>
|
||||
<li data-id="<?= $facultad['facultad_id'] ?>" class="pl-4"><?= $facultad['facultad_nombre'] ?></li>
|
||||
<?php } ?>
|
||||
@@ -384,9 +381,9 @@ if ($user->admin) {
|
||||
var button = $(event.relatedTarget);
|
||||
var tipo = button.data('tipo');
|
||||
var modal = $(this);
|
||||
setDatalistFirst('#mrol');
|
||||
// setDatalistFirst('#mrol');
|
||||
<?php if ($user->admin) { ?>
|
||||
setDatalistFirst("#dlfacultad");
|
||||
// setDatalistFirst("#dlfacultad");
|
||||
<?php } ?>
|
||||
$("#mnombre").removeClass("is-invalid");
|
||||
$("#mclave").removeClass("is-invalid");
|
||||
@@ -398,7 +395,7 @@ if ($user->admin) {
|
||||
$('#mnombre').val("");
|
||||
$('#mcorreo').val("");
|
||||
$('#id').val("");
|
||||
<?php if ($user->admin) { ?>
|
||||
<?php if (!$user->facultad['facultad_id']) { ?>
|
||||
$('#mfacultad').val(<?= $fac ?>);
|
||||
<?php } ?>
|
||||
}
|
||||
@@ -422,9 +419,9 @@ if ($user->admin) {
|
||||
$('#mclave').val(result['usuario_clave']);
|
||||
$('#mcorreo').val(result['usuario_correo']);
|
||||
setDatalist('#mrol', result['rol_id']);
|
||||
<?php if ($user->admin) { ?>
|
||||
<? if (!$user->facultad['facultad_id']) { ?>
|
||||
setDatalist('#dlfacultad', result['facultad_id']);
|
||||
<?php } ?>
|
||||
<? } ?>
|
||||
},
|
||||
error: function () {
|
||||
console.log("Error")
|
||||
@@ -441,18 +438,13 @@ if ($user->admin) {
|
||||
$('#desc-error').html("No puede tener espacios al inicio");
|
||||
error = true;
|
||||
}
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
return !error;
|
||||
}
|
||||
|
||||
$(document).on("click", ".btn-reset", function (event) {
|
||||
var forma = $(this).parents("form");
|
||||
forma.find("input[type=text]").val("");
|
||||
setDatalistFirst("#filter_rol");
|
||||
// setDatalistFirst("#filter_rol");
|
||||
forma.submit();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -9,7 +9,7 @@ if (!isset($_SESSION['user']))
|
||||
$user = unserialize($_SESSION['user']);
|
||||
|
||||
$user->access('reporte_de_asistencias');
|
||||
if ( !$user->admin && $user->acceso == 'n' )
|
||||
if ( $user->acceso == null )
|
||||
die(header('Location: main.php?error=1'));
|
||||
|
||||
$user->print_to_log('Consultar: Reporte de asistencias de profesor');
|
||||
|
||||
Reference in New Issue
Block a user