This commit is contained in:
2023-10-03 18:22:51 +00:00
parent 6f4ee51b55
commit c927cb02bb
22 changed files with 800 additions and 335 deletions

View File

@@ -14,7 +14,8 @@ $ruta = "../";
require_once "../include/bd_pdo.php";
$facultad_id = $user->facultad['facultad_id'];
$carreras = $db->query(
"SELECT * FROM carrera
"SELECT carrera_id, carrera_nombre, clave_carrera
FROM carrera
WHERE
(facultad_id = :facultad_id OR :facultad_id IS NULL)
ORDER BY carrera_nombre DESC",
@@ -23,4 +24,4 @@ $carreras = $db->query(
// $user->print_to_log("Crea carrera", old: $_POST);
die(json_encode($carreras));
die(json_encode($carreras));

View File

@@ -26,9 +26,14 @@ try {
exit;
}
});
// step 1: get subrutas
$data = $db->get('facultad');
$data = $db->query(<<<SQL
SELECT facultad_nombre, facultad_id, clave_dependencia
FROM facultad
WHERE facultad_id = :facultad_id OR :facultad_id IS NULL
SQL
,
[':facultad_id' => $user->facultad['facultad_id']]
);
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
} else {
http_response_code(405);

View File

@@ -1,21 +1,41 @@
<?php
header('Content-Type: application/json');
$ruta = "../";
require_once "../class/c_login.php";
// check if the session is started
$user = Login::get_user();
if (Login::is_logged())
$user = Login::get_user();
else {
header('HTTP/1.1 401 Unauthorized');
echo json_encode(['error' => 'No se ha iniciado sesión']);
exit();
}
$ruta = "../";
require_once("../include/bd_pdo.php");
extract($_POST);
$params = ['per' => $_POST['periodo'], 'fac' => $_POST['facultad'], 'car' => $_POST['carrera']];
$user->print_to_log("Acceso a grupos", old: $params);
$grupos = queryAll("SELECT DISTINCT LENGTH(GRUPO), GRUPO FROM fs_horario_basic WHERE PERIODO_ID = COALESCE(:per, PERIODO_ID) AND FACULTAD_ID = COALESCE(:fac, FACULTAD_ID) AND CARRERA_ID = COALESCE(:car, CARRERA_ID) ORDER BY LENGTH(GRUPO), GRUPO", $params);
if (!isset($_GET['carrera_id'])) {
echo json_encode([
'status' => 'error',
'error' => 'No se ha especificado una carrera'
]);
exit();
}
$grupos = array_map(fn ($grupo) => $grupo['grupo'], $grupos);
$grupos = $db->query(<<<SQL
SELECT distinct substring(horario_grupo, 7, 3)::int - 1 as horario_grupo FROM horario_view WHERE
PERIODO_ID = :periodo_id AND
(FACULTAD_ID = :facultad_id OR :facultad_id IS NULL) AND
CARRERA_ID = :carrera_id
GROUP BY horario_grupo
ORDER BY horario_grupo ASC
SQL,
[
':periodo_id' => $user->periodo_id,
':facultad_id' => $user->facultad['facultad_id'],
':carrera_id' => $_GET['carrera_id']
]
);
echo json_encode([
'status' => 'success',
'grupos' => $grupos
]);
echo json_encode(array_map(fn($grupo) => $grupo['horario_grupo'], $grupos));

View File

@@ -17,20 +17,34 @@ $user = unserialize($_SESSION['user']);
// check method
try {
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (!isset($_GET['profesor_id'])) {
if (!(isset($_GET['profesor_id']) || isset($_GET['grupo']))) {
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
if (isset($_GET['profesor_id'])) {
$data = $db->query(
"SELECT *, (EXTRACT(EPOCH FROM (horario_fin - horario_hora) ) / EXTRACT(EPOCH FROM interval '15 minute'))::INT AS bloques
FROM horario_view
JOIN horario_profesor ON horario_profesor.horario_id = horario_view.horario_id
WHERE horario_profesor.profesor_id = :profesor_id
AND (facultad_id = :facultad_id OR :facultad_id IS NULL)",
[
'profesor_id' => $_GET['profesor_id'],
'facultad_id' => $user->facultad['facultad_id'],
]
);
[
'profesor_id' => $_GET['profesor_id'],
'facultad_id' => $user->facultad['facultad_id'],
]
);
} else if (isset($_GET['grupo'])) {
$data = $db->query(
"SELECT *, (EXTRACT(EPOCH FROM (horario_fin - horario_hora) ) / EXTRACT(EPOCH FROM interval '15 minute'))::INT AS bloques
FROM horario_view
WHERE substring(horario_grupo, 7, 3) = (CAST(:grupo AS INT) + 1)::varchar
AND (facultad_id = :facultad_id OR :facultad_id IS NULL) AND carrera_id = :carrera_id",
[
'grupo' => $_GET['grupo'],
'facultad_id' => $user->facultad['facultad_id'],
'carrera_id' => $_GET['carrera_id'],
]
);
}
$last_query = [
'query' => $db->getLastQuery(),

View File

@@ -1,26 +1,30 @@
<?php
header('Content-Type: application/json');
$ruta = "../";
require_once "../class/c_login.php";
extract($_POST);
# print_r($_POST); exit;
// check if the session is started
if (!isset($_SESSION['user']))
die(header('Location: index.php'));
die(json_encode(['error' => 'No se ha iniciado sesión']));
$user = unserialize($_SESSION['user']);
if (($access = $user->access('asistencia')) == 'n')
die(json_encode(['error' => true]));
$user->print_to_log('Consultar materias');
$materias = queryAll(
"SELECT id, nombre FROM FS_MATERIA WHERE carrera = COALESCE(:carrera, carrera) ORDER BY nombre",
[':carrera' => empty($carrera) ? null : $carrera]
$ruta = "../";
require_once "../include/bd_pdo.php";
$facultad_id = $user->facultad['facultad_id'];
$materias = $db->query(<<<SQL
SELECT materia_id, materia_nombre, clave_materia, materia.carrera_id
FROM materia
JOIN carrera USING (carrera_id)
JOIN facultad USING (facultad_id)
WHERE
(facultad_id = :facultad_id OR :facultad_id IS NULL)
ORDER BY carrera_nombre DESC
SQL,
array('facultad_id' => $facultad_id)
);
?>
<?= json_encode([
'status' => 'success',
'materias' => $materias,
]); ?>
// $user->print_to_log("Crea carrera", old: $_POST);
die(json_encode($materias));

36
action/carrera.php Normal file
View File

@@ -0,0 +1,36 @@
<?php
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
header('Content-Type: application/json');
if (!Login::is_logged()) {
header('HTTP/1.1 401 Unauthorized');
echo json_encode(['error' => 'No se ha iniciado sesión']);
exit();
}
$user = Login::get_user();
try {
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
// Fetch all puestos
$facultad_id = $user->facultad['facultad_id'];
$carreras = $db->query(<<<SQL
SELECT carrera_id, carrera_nombre, clave_carrera, facultad_id
FROM carrera
WHERE facultad_id = :facultad_id OR :facultad_id IS NULL
SQL, ['facultad_id' => $facultad_id]);
echo json_encode($carreras);
break;
default:
header('HTTP/1.1 405 Method Not Allowed');
echo json_encode(['error' => 'Método no permitido']);
break;
}
} catch (PDOException $e) {
echo json_encode([
'error' => $e->getMessage(),
'query' => $db->getLastQuery(),
'exception' => $e->getTraceAsString()
]);
}

View File

@@ -26,7 +26,7 @@ try {
->join('puesto_usuario', 'puesto_usuario.usuario_id = usuario.usuario_id', 'LEFT')
->getOne('usuario', ['usuario.usuario_id', 'usuario_nombre', 'usuario_clave']),
),
$db->orderBy('puesto_id', 'desc')
$db->orderBy('puesto.nombre', 'desc')
->where('facultad_id', $facultad_id)
->get(tableName: 'puesto', numRows: count($carreras), columns: 'puesto_id, nombre'),
);
@@ -61,7 +61,7 @@ try {
$raw_input = file_get_contents('php://input');
$input_data = json_decode($raw_input, true);
if (!$input_data || !isset($input_data['puesto_id'], $input_data['materias'], $input_data['usuario_id'])) {
if (!$input_data || !isset($input_data['puesto_id'], $input_data['materias'])) {
header('HTTP/1.1 400 Bad Request');
echo json_encode(['error' => 'Datos inválidos']);
exit();
@@ -77,10 +77,11 @@ try {
]);
}
$db->insert('puesto_usuario', [
'puesto_id' => $input_data['puesto_id'],
'usuario_id' => $input_data['usuario_id'],
]);
if (isset($input_data['usuario_id']))
$db->insert('puesto_usuario', [
'puesto_id' => $input_data['puesto_id'],
'usuario_id' => $input_data['usuario_id'],
]);
echo json_encode(['msg' => 'Puesto actualizado exitosamente']);
break;
@@ -95,7 +96,7 @@ try {
exit();
}
$db->where('puesto_id', $input_data['puesto_id'])->delete('puestos');
$db->where('puesto_id', $input_data['puesto_id'])->delete('puesto');
echo json_encode(['msg' => 'Puesto eliminado exitosamente']);
break;

View File

@@ -7,12 +7,14 @@ $ruta = "../";
require_once "../class/c_login.php";
// check if the session is started
$user = Login::get_user();
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();
@@ -21,30 +23,31 @@ if(!isset($_POST["id"]) || !isset($_POST["edo"]) ){
$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
$salon = filter_input(INPUT_POST, "salon", FILTER_SANITIZE_NUMBER_INT);//limpia texto
$motivo = "";
if(isset($_POST["motivo"]) && $_POST["motivo"] != "")
$motivo = trim($_POST["motivo"]);
if($edo == 4){//cancelación
$motivo = "";
if(isset($_POST["motivo"]) && $_POST["motivo"] != "")
$motivo = trim($_POST["motivo"]);
$db->querySingle('SELECT fu_reposicion_cancela(:id, :motivo)',
[':id' => $id_repo, ':motivo' => $motivo]
);
}else{
if(!empty($salon)){
$db->querySingle('SELECT fu_reposicion(:id, NULL, NULL, NULL, :sal, :edo, NULL, NULL, NULL, NULL)',
$db->querySingle('SELECT fu_reposicion_solicitud(:id, NULL, NULL, NULL, :sal, :edo, NULL, NULL, NULL, NULL)',
[':id' => $id_repo, ':sal' => $salon, ':edo' => $edo]
);
}else{
$db->querySingle('SELECT fu_reposicion(:id, NULL, NULL, NULL, NULL, :edo, NULL, NULL, NULL, NULL)',
$db->querySingle('SELECT fu_reposicion_solicitud(: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 = $pdo->prepare('Select * from
:id, :periodo, NULL, NULL, NULL, NULL, NULL, 0, 1)');
$stmt->bindParam(":id", $id_repo);
$stmt->bindParam(":periodo", $_SESSION["periodo_id"]);
if(!$stmt->execute()){

View File

@@ -7,17 +7,20 @@ $ruta = "../";
require_once "../class/c_login.php";
// check if the session is started
$user = Login::get_user();
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"])){
if(!isset($_POST["id"])){
$return["error"] = "Error! No se recibió la información necesaria.";
}else{
$id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT);//limpia texto
$prof = $user["id"];
$creador = $user->user["id"];
try{
$db->query('SELECT * from fd_reposicion(:id, :prof)', [":id"=> $id, ":prof"=>$prof]);
$db->query('SELECT * from fd_reposicion_solicitud(:id, :creador)', [":id"=> $id, ":creador"=>$creador]);
$return["ok"] = "La reposición se borró correctamente";
}catch(Exception $e){

View File

@@ -55,7 +55,17 @@ $user = unserialize($_SESSION['user']);
$return["materia"] = $rs["materia_id"];
$return["materia_desc"] = $rs["materia_nombre"];
$return["salon"] = $rs["salon_id"];
$return["salon_desc"] = $rs["salon"]=="" ? "-Pendiente-": $rs["salon"];
if($rs["salon_id"]==""){
$return["salon_desc"] = "Pendiente";
}else{
$salon_json = json_decode($rs["salon_array"], true);
if($salon_json[0]== "UNIVERSIDAD LA SALLE"){
unset($salon_json[0]);
}
$return["salon_desc"] = join(" / ",$salon_json);
}
//$return["salon_desc"] = $rs["salon"]=="" ? "-Pendiente-": $rs["salon"];
$return["ciclo"] = $rs["ciclo"];
$return["bloque"] = $rs["bloque"];
$return["profesor"] = $rs["profesor_id"];
@@ -69,6 +79,7 @@ $user = unserialize($_SESSION['user']);
$return["dia"] = date('w', strtotime($rs["fecha_clase"]));
$return["motivo_cancelacion"] = $rs["motivo_cancelacion"];
$return["estado"] = $rs["estado_reposicion_id"];
$return["facultad"] = $rs["facultad_nombre"];
}
echo json_encode($return);
?>

View File

@@ -60,7 +60,6 @@ try {
'reposicion_hora',
'salon_reposicion.salon as reposicion_salon',
];
$data = array_map(
fn($ruta) => array_merge(
[
@@ -77,6 +76,8 @@ try {
->where('horario_dia = EXTRACT(DOW FROM CURRENT_DATE)')
->where('bloque_horario.id', $_GET['bloque_horario_id'])
->where('salon_view.id_espacio_padre', $ruta['id_espacio_sgu'])
->orderBy('horario_hora')
->orderBy('salon_view.salon')
->get(
'horario_view',
columns: $columns

28
action/usuarios.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
header('Content-Type: application/json');
$ruta = "../";
require_once "../class/c_login.php";
// check if the session is started
if (!isset($_SESSION['user']))
die(json_encode(['error' => 'No se ha iniciado sesión']));
$user = unserialize($_SESSION['user']);
$ruta = "../";
require_once "../include/bd_pdo.php";
$facultad_id = $user->facultad['facultad_id'];
$materias = $db->query(<<<SQL
SELECT usuario_id, usuario_nombre, usuario_clave
FROM usuario
WHERE
(facultad_id = :facultad_id OR :facultad_id IS NULL)
ORDER BY usuario_nombre ASC
SQL,
array('facultad_id' => $facultad_id)
);
// $user->print_to_log("Crea carrera", old: $_POST);
die(json_encode($materias));

View File

@@ -218,7 +218,16 @@
<div class="mt-3 d-flex justify-content-between flex-wrap align-items-center">
<!-- botón descargar -->
<div class="col-md-5 col-12 text-center">
<div class="col-md-2 col-12 text-center">
<div class="btn-group my-3">
<button type="button" class="btn btn-outline-primary mr-3">
Justificar profesores
<i class="ing-justificar"></i>
</button>
</div>
</div>
<!-- botón descargar -->
<div class="col-md-2 col-12 text-center">
<div class="btn-group my-3" v-if="store.registros.relevant.length > 0">
<button type="button" class="btn btn-outline-primary mr-3" @click="store.registros.descargar">
Descargar reporte
@@ -233,7 +242,7 @@
</div>
</div>
<!-- Reporte -->
<div class="col-md-7 col-12 justify-content-around d-flex align-items-center">
<div class="col-md-8 col-12 justify-content-around d-flex align-items-center">
<span v-for="estado in store.estados.data" :class="`text-${estado.estado_color}`"
class="text-center col-2">
<i :class="`${estado.estado_icon} ing-lg`"></i>
@@ -313,7 +322,8 @@
<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>
<strong v-if="registro.usuario_nombre">{{ registro.usuario_nombre
}}</strong>
</div>
<div class="col-12" v-if="registro.registro_fecha_supervisor">
Hora
@@ -452,7 +462,8 @@
</div>
<div class="col-12">
<strong>Horario:</strong>
{{ clase_vista.horario_hora?.slice(0, 5) }} - {{clase_vista.horario_fin?.slice(0, 5) }}
{{ clase_vista.horario_hora?.slice(0, 5) }} -
{{clase_vista.horario_fin?.slice(0, 5) }}
</div>
<div class="col-12">
<strong>Salón:</strong>
@@ -602,20 +613,8 @@
class="text-muted">{{store.current.justificada.profesor_nombre}}</span>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<div class="form-check" v-if="!store.current.justificada.justificacion">
<input class="form-check-input" type="checkbox" value="" id="observaciones"
v-model="store.current.observaciones">
<label class="form-check-label" for="observaciones">
¿Deseas añadir observaciones?
</label>
</div>
</div>
</div>
<hr v-if="store.current.observaciones || store.current.justificada.justificacion">
<div class="input-group" v-if="store.current.observaciones || store.current.justificada.justificacion">
<hr>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text text-white bg-primary">Observaciones</span>
</div>
@@ -632,7 +631,10 @@
<i class="ing-cancelar"></i>
Cancelar
</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" @click="store.justificar">
<button type="button" class="btn btn-primary"
:disabled="!store.current.justificada.justificacion"
:class="{'disabled': !store.current.justificada.justificacion}" data-dismiss="modal"
@click="store.justificar">
Justificar
</button>
</div>

View File

@@ -37,29 +37,99 @@ $write = $user->admin || in_array($user->acceso, ['r']);
include("import/html_header.php");
html_header("Consultar horario", "Sistema de gestión de checador");
?>
<main class="container px-4 mt-4 h-100" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;">
<main class="container px-4 mt-4 h-100" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;"
v-scope="">
<section id="message"></section>
<? // 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>
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<button class="nav-link active" id="nav-home-tab" data-toggle="tab" data-target="#nav-home"
type="button" role="tab" aria-controls="nav-home" aria-selected="true" @click="horarios.data = []">
Horario por profesor
</button>
<button class="nav-link" id="nav-profile-tab" data-toggle="tab" data-target="#nav-profile" type="button"
role="tab" aria-controls="nav-profile" aria-selected="false" @click="horarios.data = []">
Horario por grupo
</button>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">
<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(null)">
<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>
<datalist id="dlProfesor">
<option v-for="profesor in profesores.data" :key="profesor.profesor_id"
:value="`(${profesor.profesor_clave}) ${profesor.profesor_nombre}`">
</datalist>
</div>
</div>
<div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab"
v-scope="{facultad_id: null, carrera_id: null, grupo: null}">
<?
require('import/periodo.php');
?>
<div class="form-box" v-show="facultades.data.every(facultad => facultad.carreras.length > 0)">
<div class="form-group row">
<label for="carrera_id" class="col-4 col-form-label">Carrera</label>
<div class="col-6">
<div id="dlCarreras" class="datalist datalist-select mb-1 w-100">
<div class="datalist-input">
Selecciona una carrera
</div>
<span class="icono ing-buscar"></span>
<ul style="display:none">
<div v-for="facultad in facultades.data">
<li class="not-selectable">
{{ facultad.facultad_nombre }}
</li>
<li v-for="carrera in facultad.carreras" :key="carrera.carrera_id"
@click="carrera_id = carrera.carrera_id; facultad_id = facultad.facultad_id; grupo = null">
{{ carrera.carrera_nombre }}
</li>
</div>
</ul>
<input type="hidden" id="carrera_id" name="id">
</div>
</div>
</div>
</div>
<div class="form-box" v-if="carrera_id">
<div class="form-group row">
<label for="grupo" class="col-4 col-form-label">Grupo</label>
<div class="col-6">
<div id="dlGrupo" class="datalist datalist-select mb-1 w-100">
<div class="datalist-input">
Selecciona un grupo
</div>
<span class="icono ing-buscar"></span>
<ul style="display:none">
<li v-for="grupo in facultades.data.find(facultad => facultad.facultad_id === facultad_id).carreras.find(carrera => carrera.carrera_id === carrera_id).grupos"
@click="grupo = grupo; horarios.fetch(grupo, carrera_id)">
{{ grupo }}
</li>
</ul>
<input type="hidden" id="grupo" name="grupo">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<div id="btn-excel-horario" class="mb-2 float-right hidden">
<button class="btn btn-outline-secondary " title="Exportar a Excel" v-if="false">
@@ -94,8 +164,7 @@ $write = $user->admin || in_array($user->acceso, ['r']);
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;
<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">
@@ -111,12 +180,14 @@ $write = $user->admin || in_array($user->acceso, ['r']);
{{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>
<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> &nbsp; </div>
</div>

View File

@@ -14,10 +14,32 @@ const profesores = reactive({
return this.data.find((profesor) => profesor.profesor_clave === profesores.clave);
},
});
const horarios = reactive({
const facultades = reactive({
data: [],
fetch: async function () {
if (profesores.current) {
const facultades = await fetch('action/action_facultad.php').then(response => response.json());
const carreras = await fetch(`action/carrera.php`).then(response => response.json());
this.data = await Promise.all(facultades.map(async (facultad) => ({
...facultad,
carreras: await Promise.all(carreras.filter((carrera) => carrera.facultad_id === facultad.facultad_id).map(async (carrera) => {
const grupos = await fetch(`action/action_grupo.php?carrera_id=${carrera.carrera_id}`).then(response => response.json());
return {
...carrera,
grupos,
};
})),
})));
this.data = this.data.filter((facultad) => facultad.carreras.length > 0);
}
});
const horarios = reactive({
data: [],
fetch: async function (grupo = null, carrera_id = null) {
if (grupo && carrera_id) {
const response = await fetch(`action/action_horario.php?grupo=${grupo}&carrera_id=${carrera_id}`);
this.data = await response.json();
}
else if (profesores.current) {
const response = await fetch(`action/action_horario.php?profesor_id=${profesores.current.profesor_id}`);
this.data = await response.json();
}
@@ -76,7 +98,9 @@ const horarios = reactive({
const app = createApp({
profesores,
horarios,
facultades,
mounted: async function () {
await profesores.fetch();
await facultades.fetch();
}
}).mount('#app');

View File

@@ -15,6 +15,31 @@ const app = createApp({
});
const data = await res.json();
this.puestos.push(data);
// order by puesto.nombre
this.puestos.sort((a, b) => a.nombre.localeCompare(b.nombre));
}
catch (error) {
alert(`Error: ${error}`);
}
},
to_delete: null,
async eliminarPuesto(puesto_id) {
try {
const res = await fetch('action/puesto.php', {
method: 'DELETE',
body: JSON.stringify({
puesto_id
})
});
const data = await res.json();
this.message = data.msg;
// after 3 seconds, remove the message
setTimeout(() => {
this.message = null;
}, 3000);
this.puestos = this.puestos.filter((p) => p.puesto_id !== puesto_id);
// order by puesto.nombre
this.puestos.sort((a, b) => a.nombre.localeCompare(b.nombre));
}
catch (error) {
alert(`Error: ${error}`);

View File

@@ -49,7 +49,7 @@
<?
global $db;
$registros = $db
->where('momento::DATE = CURRENT_DATE')
->where('momento::DATE = ' . (isset($_GET['fecha']) ? "'{$_GET['fecha']}'" : 'CURRENT_DATE'))
->orderBy('momento', 'desc')
->get('log_registro');

View File

@@ -26,164 +26,243 @@
global $user;
html_header(
"Puestos de la {$user->facultad['facultad']}",
is_null($user->facultad['facultad_id']) ? "Puestos" : "Puestos de la {$user->facultad['facultad']}",
"Sistema de gestión de checador",
);
?>
if (!is_null($user->facultad['facultad_id'])) {
?>
<main class="container-fluid px-4 mt-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 70vh;"
v-scope="{new_puesto: null}">
<main class="container-fluid px-4 mt-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 70vh;"
v-scope="{new_puesto: null}">
<div class="alert alert-success" role="alert" v-if="message">
{{message}}
</div>
<div class="justify-content-between align-items-center d-flex mb-4">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#nuevo-puesto">
<span class="ing-mas"></span>
Agregar puesto
</button>
</div>
<div class="d-flex flex-wrap justify-content-around">
<div class="col-6" v-for="puesto in puestos" :key="puesto.puesto_id">
<div class="card text-center"
v-scope="{selected_carrera_id: -1, current_materia: null, current_encargado: null}">
<div class="card-header bg-primary text-white font-weight-bold text-uppercase">
{{puesto.nombre}}
</div>
<div class="card-body">
<!-- Encargado -->
<div class="form-row justify-content-around align-items-center mb-2">
<label :for="`encargado-${puesto.puesto_id}`" class="col-3">
Encargado del área
</label>
<div id="encargados" class="datalist datalist-select mb-1 col-9">
<div class="datalist-input" v-if="puesto.encargado">
({{puesto.encargado.usuario_clave}}) {{ puesto.encargado.usuario_nombre }}
</div>
<div class="datalist-input" v-else>
Selecciona un encargado
</div>
<span class="icono ing-buscar"></span>
<ul style="display:none">
<li class="datalist-option" v-for="usuario in usuarios" :key="usuario.usuario_id"
:data-id="usuario.usuario_id" style=" white-space: nowrap;"
@click="puesto.encargado = usuario"
:class="{'selected': puesto.encargado.usuario_id == usuario.usuario_id}">
(<small> {{usuario.usuario_clave}} </small>) {{ usuario.usuario_nombre }}
</li>
</ul>
<input type="hidden" id="encargado_id" name="id">
</div>
<div class="alert alert-success" role="alert" v-if="message">
{{message}}
</div>
<div class="justify-content-between align-items-center d-flex mb-4">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#nuevo-puesto">
<span class="ing-mas"></span>
Agregar puesto
</button>
</div>
<div class="d-flex flex-wrap justify-content-around">
<div class="accordion col-8 mb-4" id="puestos"
v-scope="{selected_carrera_id: -1, current_materia: null, current_encargado: null}"
v-if="puestos.length">
<div class="card" v-for="(puesto, index) in puestos" :key="puesto.puesto_id">
<div class="card-header bg-primary" :id="`puesto-${puesto.nombre}`">
<h2 class="mb-0">
<button class="btn btn-link btn-block text-left text-light" type="button"
data-toggle="collapse" :data-target="`#puesto-${puesto.puesto_id}`" aria-expanded="true"
:aria-controls="`puesto-${puesto.puesto_id}`">
{{puesto.nombre}}
<button type="button" class="btn btn-outline-danger float-right"
data-target="#eliminar-puesto" data-toggle="modal" @click="to_delete = puesto">
<span class="icono ing-basura"></span>
</button>
</button>
</h2>
</div>
<hr>
<fieldset class="container d-flex flex-column justify-content-center align-items-center">
<legend>Materias Asignadas <span
class="badge badge-secondary">{{puesto.materias.length}}</span></legend>
<ul class="list-group overflow-auto col-10" v-if="puesto.materias.length"
style="max-height: 200px; overflow-y: auto;">
<li class="list-group-item list-group-item-action" v-for="materia in puesto.materias"
:key="materia.materia_id"
@click="puesto.materias.splice(puesto.materias.indexOf(materia), 1); materias.push(materia)"
style="cursor: pointer;">
<div class="d-flex justify-content-center">
<div class="col-2">
<span class="icono ing-borrar text-danger"></span>
<div :id="`puesto-${puesto.puesto_id}`" class="collapse" :class="{'show': index == 0}"
:aria-labelledby="`puesto-${puesto.nombre}`" data-parent="#puestos">
<div class="card-body">
<!-- Encargado -->
<div class="form-row justify-content-around align-items-center mb-2">
<label :for="`encargado-${puesto.puesto_id}`" class="col-3">
Encargado del área
</label>
<div id="encargados" class="datalist datalist-select mb-1 col-9">
<div class="datalist-input" v-if="puesto.encargado">
({{puesto.encargado.usuario_clave}}) {{ puesto.encargado.usuario_nombre }}
</div>
<div class="col-10 text-left">
{{materia.clave_materia}} - {{materia.materia_nombre}}
<div class="datalist-input" v-else>
Selecciona un encargado
</div>
<span class="icono ing-buscar"></span>
<ul style="display:none">
<li class="datalist-option" v-for="usuario in usuarios"
:key="usuario.usuario_id" :data-id="usuario.usuario_id"
style=" white-space: nowrap;" @click="puesto.encargado = usuario"
:class="{'selected': puesto.encargado?.usuario_id == usuario.usuario_id}">
(<small> {{usuario.usuario_clave}} </small>) {{ usuario.usuario_nombre }}
</li>
</ul>
<input type="hidden" id="encargado_id" name="id">
</div>
</li>
</ul>
<div class="alert alert-light" role="alert" v-else>
No hay materias asignadas
</div>
</fieldset>
<hr>
<div class="form-row justify-content-around align-items-center mb-2" v-show="carreras.length">
<label :for="`carrera-${puesto.puesto_id}`" class="col-3">
Carrera
</label>
<div id="dlCarreras" class="datalist datalist-select mb-1 col-9">
<div class="datalist-input">
Selecciona una carrera
</div>
<span class="icono ing-buscar"></span>
<ul style="display:none">
<li class="datalist-option" data-id="0" @click="selected_carrera_id = 0">
Todas las carreras
</li>
<li class="datalist-option" v-for="carrera in carreras" :key="carrera.carrera_id"
:data-id="carrera.carrera_id" style=" white-space: nowrap;"
@click="selected_carrera_id = carrera.carrera_id">
(<small> {{carrera.clave_carrera}} </small>) {{ carrera.carrera_nombre }}
</li>
</ul>
<input type="hidden" id="carrera_id" name="id">
</div>
</div>
<div class="form-row justify-content-around align-items-center"
v-scope="{to_add_materia: null}">
<label :for="`materias-${puesto.puesto_id}`" class="col-3">
Materias
</label>
<input name="materia" placeholder="Seleccione una materia" list="datalist-materias"
class="form-control col-9 " v-model="current_materia" @input="to_add_materia = materias.find(m => current_materia == `${m.clave_materia} - ${m.materia_nombre}`);
<hr>
<div class="form-row justify-content-around align-items-center mb-2"
v-show="carreras.length">
<label :for="`carrera-${puesto.puesto_id}`" class="col-3">
Carrera
</label>
<div id="dlCarreras" class="datalist datalist-select mb-1 col-9">
<div class="datalist-input">
Selecciona una carrera
</div>
<span class="icono ing-buscar"></span>
<ul style="display:none">
<li class="datalist-option" data-id="0" @click="selected_carrera_id = 0">
Todas las carreras
</li>
<li class="datalist-option" v-for="carrera in carreras"
:key="carrera.carrera_id" :data-id="carrera.carrera_id"
style=" white-space: nowrap;"
@click="selected_carrera_id = carrera.carrera_id">
(<small> {{carrera.clave_carrera}} </small>) {{ carrera.carrera_nombre }}
</li>
</ul>
<input type="hidden" id="carrera_id" name="id">
</div>
</div>
<div class="form-row justify-content-around align-items-center"
v-scope="{to_add_materia: null}">
<label :for="`materias-${puesto.puesto_id}`" class="col-3">
Materias
</label>
<input name="materia" placeholder="Seleccione una materia" list="datalist-materias"
class="form-control col-9 " v-model="current_materia" @input="to_add_materia = materias.find(m => current_materia == `${m.clave_materia} - ${m.materia_nombre}`);
if (to_add_materia) {
if (puesto.materias.find(p => p.materia_id == to_add_materia.materia_id)) {
console.log('La materia ya está asignada');
current_materia = null;
return;
}
puesto.materias.push(to_add_materia);
materias.splice(materias.indexOf(to_add_materia), 1);
current_materia = null;
}" :disabled="selected_carrera_id == -1" v-model="current_materia"
:id="`materias-${puesto.puesto_id}`">
</div>
<datalist id="datalist-materias">
<option
v-for="materia in materias.filter(m => selected_carrera_id == 0 || m.carrera_id == selected_carrera_id)"
:value="`${materia.clave_materia} - ${materia.materia_nombre}`">
</datalist>
</div>
<div class="card-footer text-muted">
<button type="button" class="btn btn-outline-primary btn-lg btn-block" v-if="puesto.encargado"
@click="actualizarPuesto(puesto.puesto_id, puesto.materias, puesto.encargado.usuario_id)">
Guardar cambios
</button>
</div>
</div>
</div>
</div>
:id="`materias-${puesto.puesto_id}`" autocomplete="off">
</div>
<datalist id="datalist-materias">
<option
v-for="materia in materias.filter(m => selected_carrera_id == 0 || m.carrera_id == selected_carrera_id).filter(m => !puesto.materias.find(p => p.materia_id == m.materia_id))"
:value="`${materia.clave_materia} - ${materia.materia_nombre}`">
</datalist>
<hr>
<fieldset class="container d-flex flex-column justify-content-center align-items-center">
<legend>Materias Asignadas <span
class="badge badge-secondary">{{puesto.materias.length}}</span></legend>
<ul class="list-group overflow-auto col-10" v-if="puesto.materias.length"
style="max-height: 200px; overflow-y: auto;">
<li class="list-group-item list-group-item-action"
v-for="materia in puesto.materias" :key="materia.materia_id"
@click="puesto.materias.splice(puesto.materias.indexOf(materia), 1); materias.push(materia)"
style="cursor: pointer;">
<div class="d-flex justify-content-center">
<div class="col-2 text-center">
<span class="icono ing-borrar text-danger"></span>
</div>
<div class="col-10 text-left">
{{materia.clave_materia}} - {{materia.materia_nombre}}
</div>
</div>
</li>
</ul>
<div class="alert alert-light" role="alert" v-else>
No hay materias asignadas
</div>
</fieldset>
<div class="modal" tabindex="-1" role="dialog" accesskey="a" id="nuevo-puesto">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header text-white">
<h5 class="modal-title">Agregar un nuevo puesto</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" class="text-white">&times;</span>
</button>
</div>
<div class="modal-body">
<fieldset>
<legend>Nombre del puesto</legend>
<div class="form-row">
<input type="text" class="form-control" v-model="new_puesto"
placeholder="Área del puesto">
</div>
</fieldset>
<div class="card-footer text-muted">
<!-- scroll to top -->
<button type="button" class="btn btn-outline-primary btn-lg btn-block"
@click="actualizarPuesto(puesto.puesto_id, puesto.materias, puesto.encargado?.usuario_id)"
onclick="window.scrollTo(0, 0);">
{{ puesto.encargado ? 'Guardar cambios' : 'Guardar sin encargado' }}
</button>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-danger" data-dismiss="modal"
@click="new_puesto = null">Cancelar</button>
<button type="button" class="btn btn-primary" data-dismiss="modal"
@click="nuevoPuesto(new_puesto)">Guardar</button>
</div>
<div v-else>
<div class="alert alert-dark" role="alert">
No hay puestos registrados
</div>
</div>
</div>
</div>
</main>
<? include "import/html_footer.php"; ?>
<div class="modal" tabindex="-1" role="dialog" accesskey="a" id="nuevo-puesto">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header text-white">
<h5 class="modal-title">Agregar un nuevo puesto</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" class="text-white">&times;</span>
</button>
</div>
<div class="modal-body">
<fieldset>
<legend>Nombre del puesto</legend>
<div class="form-row">
<input type="text" class="form-control" v-model="new_puesto"
placeholder="Área del puesto">
</div>
</fieldset>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-danger" data-dismiss="modal"
@click="new_puesto = null">Cancelar</button>
<button type="button" class="btn btn-primary" data-dismiss="modal"
@click="nuevoPuesto(new_puesto); new_puesto = null">Guardar</button>
</div>
</div>
</div>
</div>
<div class="modal" tabindex="-1" role="dialog" accesskey="a" id="eliminar-puesto">
<div class="modal-dialog modal-dialog-centered" role="document" v-if="to_delete">
<div class="modal-content">
<div class="modal-header text-white">
<h5 class="modal-title">Eliminar puesto</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" class="text-white">&times;</span>
</button>
</div>
<div class="modal-body">
<fieldset>
<legend>¿Estás seguro de que deseas eliminar el puesto?</legend>
<p>Esta acción no se puede deshacer. Se perderán las asignaciones de materias y de
encargado.</p>
</fieldset>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-danger" data-dismiss="modal"
@click="new_puesto = null">Cancelar</button>
<button type="button" class="btn btn-danger" data-dismiss="modal"
@click="eliminarPuesto(to_delete.puesto_id)">Eliminar</button>
</div>
</div>
</div>
</div>
</main>
<?
} else {
?>
<main class="container mt-5" style="min-height: 70vh;">
<div class="row">
<div class="col-md-8 offset-md-2">
<div class="card">
<div class="card-header text-white bg-danger">
Sin Facultad Asociada
</div>
<div class="card-body">
<h5 class="card-title">Atención</h5>
<p class="card-text">No tienes una facultad asociada a tu perfil. El rol
<?= $user->rol['rol'] ?> no tiene acceso a esta sección.
</p>
</div>
</div>
</div>
</div>
</main>
<? }
include "import/html_footer.php"; ?>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="js/bootstrap/bootstrap.min.js"></script>

View File

@@ -9,7 +9,7 @@ if (!isset($_SESSION['user'])){
$user = Login::get_user();
$user->access();
echo $user;
//echo $user;
/*print_r($user);
print_r($user->user["id"]);
echo "****|";
@@ -53,7 +53,7 @@ if($user->periodo_id!= ""){
$carrera_rs = $db->query('SELECT * FROM fs_profesor_facultad(NULL, :periodo)', [ ':periodo' => $user->periodo_id]);
}
$salones_rs = $db->query('SELECT * FROM salon_view WHERE tiene_salones IS true');
$salones_rs = $db->query('SELECT * from salon_view where es_salon 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_id]);
@@ -227,7 +227,7 @@ if($user->periodo_id!= ""){
<a class="nav-link" id="tab3-tab" data-toggle="tab" href="#tab3" role="tab" aria-controls="lista" aria-selected="false">Autorizadas por Vicerrectoría</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>
<a class="nav-link" id="tab4-tab" data-toggle="tab" href="#tab4" role="tab" aria-controls="lista" aria-selected="false">Declinadas</a>
</li>
</ul>
<div class="tab-content" id="TabContent">
@@ -303,7 +303,8 @@ if($user->periodo_id!= ""){
</td>
<td class="text-center align-middle"><?php
if($reposicion["salon_id"] != ""){
echo $reposicion["salon_id"];
$salon_json = json_decode($reposicion["salon_array"], true);
echo $salon_json[count($salon_json)-1];
}else
echo "Pendiente";
?>
@@ -313,13 +314,13 @@ if($user->periodo_id!= ""){
<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){?>
if((!$user->jefe_carrera || $user->admin || !$coordinador) && $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){?>
else if(($supervisor || $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>
<a href="#" data-toggle="modal" data-target="#modal_aprobar" data-tipo="1" title="Ver detalle"><?php echo $ICO["ver"];?></a>
<?php } ?>
<?php
}else{ //fecha ya pasó?>
@@ -375,6 +376,14 @@ if($user->periodo_id!= ""){
<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">Dependencia</p>
</div>
<div class="col-6">
<p class="rep-fac"></p>
</div>
</div>
<div class="row">
<div class="col-6 col-sm-4 barra-right text-right">
<p class="font-weight-bold">Materia</p>
@@ -461,13 +470,18 @@ if($user->periodo_id!= ""){
<?php
foreach ($salones_rs as $salon) {
extract($salon);
$salon_json = json_decode($salon_array, true);
if($salon_json[0]== "UNIVERSIDAD LA SALLE"){
unset($salon_json[0]);
}
$salon_nombre = join(" / ",$salon_json);
?>
<option data-id="<?= $salon_id ?>" data-nombre="<?= $salon ?>" value="<?= $salon ?>"></option>
<option data-id="<?= $salon_id ?>" data-nombre="<?= $salon_nombre ?>" value="<?= $salon_nombre ?>"></option>
<?php
}
?>
</datalist>
<ul class="list-group" id="salones"></ul>
<!-- <ul class="list-group" id="salones"></ul> -->
<input type="hidden" id="salon" name="salon" value="">
</div>
</div>
@@ -610,6 +624,27 @@ if($user->periodo_id!= ""){
$("#motivo").val("")
});
$('#dlSalon').on('change', function() {
const selectedValue = $(this).val();
//console.log(selectedValue)
const selectedOption = $(`option[value="${selectedValue}"]`);
//console.log(selectedOption.length)
const salonesList = $('#salones');
if (selectedOption.length) {
const salonId = selectedOption.data('id');
$('#salon').val(salonId);
//const salonNombre = selectedOption.data('nombre');
//salonesList.html(`<li class="list-group-item">${salonNombre}</li>`);
} else {
$('#salon').val('');
//salonesList.empty();
}
});
$('#modal_aprobar').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget); // Button that triggered the modal
var id = button.parents("tr").data("id");
@@ -619,7 +654,6 @@ if($user->periodo_id!= ""){
$("#edo").val(edo);
$("#id").val(id);
$.ajax({
url: './action/reposicion_select.php',
@@ -631,8 +665,9 @@ if($user->periodo_id!= ""){
triggerMessage(result["error"], "Error");
$('#modal_aprobar').modal("hide");
}else{
$("#dlSalon").val("");
$("#modal_aprobar .rep-prof").text(result["profesor_nombre"]);
$("#modal_aprobar .rep-fac").text(result["facultad"]);
$("#modal_aprobar .rep-mat").text(result["materia_desc"]);
$("#modal_aprobar .rep-ciclo").text(result["ciclo"]);
$("#modal_aprobar .rep-bloque").text(result["bloque"]);
@@ -663,23 +698,30 @@ if($user->periodo_id!= ""){
if(edo == 1){// 1 ver
$("#modalLabel").text("Detalle de reposición");
$(".aprobar-block").hide();
/*if(parseInt($("#modal_aprobar .rep-aula").data("aula")) != 1){//tipo aula 1 (salon normal) - ver
$("#salon-ver").hide();
$("#salon-editar").show();
}else{
$("#salon-ver").show();
$("#salon-editar").hide();
}*/
$("#salon-ver").show();
$("#salon-editar").hide();
}else{
if(parseInt($("#modal_aprobar .rep-aula").data("aula")) == 1){//tipo aula 1 (salon normal) - ver
$("#modalLabel").text("Detalle de reposición");
$(".aprobar-block").hide();
$("#modalLabel").text("Aprobar reposición");
$(".aprobar-block").show();
if(edo == 2 && parseInt($("#modal_aprobar .rep-aula").data("aula")) == 1){//tipo aula 1 (salon normal) - ver
$("#salon-ver").show();
$("#salon-editar").hide();
}else if(edo == 3 && parseInt($("#modal_aprobar .rep-aula").data("aula")) != 1){//aprobar (con salón especial)
$("#salon-ver").show();
$("#salon-editar").hide();
}else{
$("#modalLabel").text("Aprobar reposición");
$(".aprobar-block").show();
if(edo == 3){//aprobar (con salón)
$("#salon-ver").hide();
$("#salon-editar").show();
}
$("#salon-ver").hide();
$("#salon-editar").show();
}
}

View File

@@ -24,7 +24,6 @@ if ($user->acceso === null && !$user->admin){
exit();
}
//if (!$user->admin && in_array($user->acceso, ['n']))
//die(header('Location: main.php?error=1'));
//$user->print_to_log('Reposiciones');
@@ -34,51 +33,59 @@ $write = true; //
$en_fecha = $db->querySingle("SELECT ESTA_EN_PERIODO(NOW()::DATE, :periodo_id)", [':periodo_id' => $user->periodo_id])['esta_en_periodo'];
if($user->jefe_carrera){
//if($user->jefe_carrera){
$prof_rs = $db->query('SELECT DISTINCT * FROM fs_profesores(null, null, :fac) ORDER BY PROFESOR_NOMBRE', [':fac' => $user->facultad["facultad_id"]]);
}
//$prof_rs = $db->query('SELECT DISTINCT * FROM fs_profesores(null, null, :fac) ORDER BY PROFESOR_NOMBRE', [':fac' => $user->facultad["facultad_id"]]);
$prof_rs = $db->query('SELECT DISTINCT PROFESOR.* FROM PUESTO_USUARIO
JOIN PUESTO_MATERIA USING (PUESTO_ID)
JOIN HORARIO_VIEW USING (MATERIA_ID)
JOIN HORARIO_PROFESOR USING (HORARIO_ID)
JOIN PROFESOR USING (PROFESOR_ID)
WHERE USUARIO_ID = :usr', [':usr' => $user->user["id"]]);
//}
//Duraciones
$duracion_rs = $db->query("select * from duracion order by duracion_interval");
//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"));
if(!is_null($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->profesor;
//$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"]));
$date = DateTime::createFromFormat('d/m/Y', $fecha_ini);
$fecha_ini_db = $date->format('Y-m-d');
$date = DateTime::createFromFormat('d/m/Y', $fecha_fin);
$fecha_fin_db = $date->format('Y-m-d');
}
/*
// Materias
$id_prof = $user->profesor;
//$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"]));
$date = DateTime::createFromFormat('d/m/Y', $fecha_ini);
$fecha_ini_db = $date->format('Y-m-d');
$date = DateTime::createFromFormat('d/m/Y', $fecha_fin);
$fecha_fin_db = $date->format('Y-m-d');
?>
<!DOCTYPE html>
@@ -132,7 +139,7 @@ $fecha_fin_db = $date->format('Y-m-d');
<?php }?>
<section id="message"></section>
<?php require('import/periodo.php') ?>
<?php if(!is_null($user->periodo_id)) { ?>
<form id="asistencia" method="post" onsubmit="return validaFechas()">
<div class="form-box">
<input type="hidden" name="facultad" value="">
@@ -160,8 +167,8 @@ $fecha_fin_db = $date->format('Y-m-d');
<?php
$reposiciones_rs = $db->query('SELECT * FROM fs_reposiciones_solicitud(:f_ini, :f_fin, :usr ,NULL, NULL)', [':f_ini' => $fecha_ini_db, ':f_fin' => $fecha_fin_db, ':usr' => $user->user["id"]]);
$reposiciones_rs = $db->query('SELECT * FROM fs_reposiciones_solicitud(:f_ini, :f_fin, :usr ,NULL, NULL)', [':f_ini' => $fecha_ini_db, ':f_fin' => $fecha_fin_db, ':usr' => $user->user["id"]]);
}
?>
<div class="row">
@@ -245,11 +252,17 @@ $fecha_fin_db = $date->format('Y-m-d');
</tbody>
</table>
</div>
<?php } else { ?>
<?php } else {
if(is_null($user->periodo_id)){ ?>
<div class="col-12 text-center">
<h4 class="mt-4 text-danger">Selecciona un periodo</h4>
</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 } ?>
<?php }
} ?>
</div>
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true">
@@ -752,15 +765,13 @@ $fecha_fin_db = $date->format('Y-m-d');
$("#filtro_final").removeClass("is-invalid");
});
$("#dlProfesor ul li").click(function(){//cambia datalist
var pid = $(this).data('id');
//busca materias del profesor
$.ajax({
function obtieneProf(pid){
return $.ajax({
url: './action/reposicion_profesor_materias.php',
type: 'POST',
dataType: 'json',
data: { id: pid, },
async: false,
//async: false,
success: function(result) {
if(result["error"]!= "" && result["error"] !== undefined){
triggerMessage(result["error"], "Error");
@@ -780,29 +791,42 @@ $fecha_fin_db = $date->format('Y-m-d');
);
$("#dlMateria ul").append(html);
}
//setDatalistFirst("#horario");
$("#dlMateria ul li:first").click();
}
},
error: function(jqXHR, textStatus, errorThrown ){
triggerMessage(errorThrown, "Error");
}
});//ajax
}
$(document).on( "click", "#dlProfesor ul li", function(event){//cambia datalist
var pid = $(this).data('id');
//busca materias del profesor
var profCarga = obtieneProf(pid);
profCarga.done(function(){
$("#dlMateria ul li:first").click();
});
});
//Actualiza días elegibles de calendario
$(document).on( "click", "#dlMateria ul li", function(event){//manda al frente de todos
_dia_valido = $(this).data('dia');
_dia_valido = $(this).data('dia');//variable global
var grupo = $(this).data("gpo");
var duracionMateria = $(this).data("duracion");
$.ajax({
$(".date-picker" ).datepicker(datepickerOptions);
var hora = $(this).data("hr");
var min = $(this).data("min");
$("#hora_ini").val(hora)
$("#min_ini").val(min)
return $.ajax({
url: './action/asistenciasprofesor_select.php',
type: 'POST',
dataType: 'json',
data: { "id": $("#prof").val(), "hor": $(this).data("id") },
//async: false,
success: function(result) {
if(result["error"]!= "" && result["error"] !== undefined){
triggerMessage(result["error"], "Error");
@@ -819,7 +843,6 @@ $fecha_fin_db = $date->format('Y-m-d');
$(this).prop('selected', true);
}
});
console.log("fin materia click");
}
},
@@ -827,12 +850,8 @@ $fecha_fin_db = $date->format('Y-m-d');
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
@@ -857,7 +876,7 @@ $fecha_fin_db = $date->format('Y-m-d');
if(result["error"]!= "" && result["error"] !== undefined){
triggerMessage(result["error"], "Error");
}else{
triggerMessage(result["ok"], "Éxito");
triggerMessage(result["ok"], "Éxito", "success");
$("#id"+r_id).remove();
}
},
@@ -919,13 +938,17 @@ $fecha_fin_db = $date->format('Y-m-d');
type: 'POST',
dataType: 'json',
data: { id: r_id },
async: true,
success: function(result) {
if(result["error"]!= "" && result["error"] !== undefined){
triggerMessage(result["error"], "Error");
$("#modal").modal('hide');
}else{
//setDatalist("#prof", result["profesor"]);
setDatalist("#prof", result["profesor"])
setDatalist("#prof", result["profesor"]);
var profCarga = obtieneProf(result["profesor"]);
//$('#salon').val(result["salon"]);
$("#fecha_falta").val(result["fecha_clase"]);
$('#hora_ini').val(result["hora_ini"]);
@@ -947,8 +970,11 @@ $fecha_fin_db = $date->format('Y-m-d');
_dia_valido = parseInt(result["dia"]);
$(".date-picker" ).datepicker(datepickerOptions);
$("#dlTipo ul li:selected").click();
console.log("llega a cambio horario"+result["horario"]);
setTimeout(setDatalist("#horario", result["horario"]), 20);// No se actualiza TODO
profCarga.done(function(){
setDatalist("#horario", result["horario"]);// No se actualiza TODO
});
setDatalist("#aula", result["aula"]);
modal.modal('show');
}

View File

@@ -38,6 +38,21 @@ type Horario = {
bloques: number;
}
type Facultad = {
clave_dependencia: string;
facultad_id: number;
facultad_nombre: string;
carreras: Carrera[];
}
type Carrera = {
carrera_id: number;
carrera_nombre: string;
clave_carrera: string;
facultad_id: number;
}
const profesores = reactive({
data: [] as Profesor[],
@@ -55,6 +70,26 @@ const profesores = reactive({
},
})
const facultades = reactive({
data: [] as Facultad[],
fetch: async function () {
const facultades = await fetch('action/action_facultad.php').then(response => response.json()) as Facultad[]
const carreras = await fetch(`action/carrera.php`).then(response => response.json()) as Carrera[]
this.data = await Promise.all(facultades.map(async facultad => ({
...facultad,
carreras: await Promise.all(carreras.filter((carrera: Carrera) => carrera.facultad_id === facultad.facultad_id).map(async (carrera: Carrera) => {
const grupos = await fetch(`action/action_grupo.php?carrera_id=${carrera.carrera_id}`).then(response => response.json())
return {
...carrera,
grupos,
}
})),
})))
this.data = this.data.filter((facultad: Facultad) => facultad.carreras.length > 0)
}
})
type Structure = {
sábado: boolean;
hora_mínima: number;
@@ -64,8 +99,12 @@ type Structure = {
const horarios = reactive({
data: [] as Horario[],
fetch: async function () {
if (profesores.current) {
fetch: async function (grupo: number | null = null, carrera_id: number | null = null) {
if (grupo && carrera_id) {
const response = await fetch(`action/action_horario.php?grupo=${grupo}&carrera_id=${carrera_id}`)
this.data = await response.json()
}
else if (profesores.current) {
const response = await fetch(`action/action_horario.php?profesor_id=${profesores.current.profesor_id}`)
this.data = await response.json()
}
@@ -134,7 +173,9 @@ const horarios = reactive({
const app = createApp({
profesores,
horarios,
facultades,
mounted: async function () {
await profesores.fetch()
await facultades.fetch()
}
}).mount('#app')

View File

@@ -41,13 +41,41 @@ const app = createApp({
})
const data = await res.json()
this.puestos.push(data)
// order by puesto.nombre
this.puestos.sort((a: Puesto, b: Puesto) => a.nombre.localeCompare(b.nombre))
} catch (error) {
alert(`Error: ${error}`)
}
},
async actualizarPuesto(puesto_id: number, materias: Materia[], usuario_id: number) {
to_delete: null as Puesto | null,
async eliminarPuesto(puesto_id: number) {
try {
const res = await fetch('action/puesto.php', {
method: 'DELETE',
body: JSON.stringify({
puesto_id
})
})
const data = await res.json()
this.message = data.msg;
// after 3 seconds, remove the message
setTimeout(() => {
this.message = null
}, 3000)
this.puestos = this.puestos.filter((p: Puesto) => p.puesto_id !== puesto_id)
// order by puesto.nombre
this.puestos.sort((a: Puesto, b: Puesto) => a.nombre.localeCompare(b.nombre))
} catch (error) {
alert(`Error: ${error}`)
}
},
async actualizarPuesto(puesto_id: number, materias: Materia[], usuario_id: number | null) {
try {
const res = await fetch('action/puesto.php', {
method: 'PUT',