New things
This commit is contained in:
@@ -12,11 +12,10 @@ require_once "../include/bd_pdo.php";
|
|||||||
global $pdo;
|
global $pdo;
|
||||||
//print_r($_POST);
|
//print_r($_POST);
|
||||||
if (!isset($_POST['periodo']) || count($_POST["periodo"])==0) {
|
if (!isset($_POST['periodo']) || count($_POST["periodo"])==0) {
|
||||||
//header("Location: ../días_festivos.php?error=1");
|
header("Location: ../días_festivos.php?error=0");
|
||||||
echo "Error no hay periodo";
|
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
$periodo = $_POST['periodo'];
|
$periodoArr = $_POST['periodo'];
|
||||||
|
|
||||||
if (isset($_POST['rango'])) {
|
if (isset($_POST['rango'])) {
|
||||||
$diaInicio = new DateTime(date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo']))));
|
$diaInicio = new DateTime(date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo']))));
|
||||||
@@ -24,27 +23,35 @@ if (isset($_POST['rango'])) {
|
|||||||
$cantidad = $diaFin->diff($diaInicio);
|
$cantidad = $diaFin->diff($diaInicio);
|
||||||
$date = date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo'])));
|
$date = date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo'])));
|
||||||
for ($dias = 0; $dias <= $cantidad->days; $dias++) {
|
for ($dias = 0; $dias <= $cantidad->days; $dias++) {
|
||||||
$sql = "SELECT fi_diasfestivos(:periodo, :dia)";
|
|
||||||
$params = [':periodo' => $periodo, ':dia' => $date];
|
$db->querySingle('SELECT fi_diasfestivos({'.implode(",",$fieldName).'}, :dia)', [':dia' => $date]);
|
||||||
query($sql, $params, false);
|
/*$sql = "SELECT fi_diasfestivos(:periodo, :dia)";
|
||||||
|
$params = [':periodo' => $periodo, ':dia' => $date];
|
||||||
|
query($sql, $params, false);*/
|
||||||
|
|
||||||
$date = date("Y-m-d", strtotime($date . "+ 1 days"));
|
$date = date("Y-m-d", strtotime($date . "+ 1 days"));
|
||||||
}
|
}
|
||||||
header("Location: ../días_festivos.php");
|
header("Location: ../días_festivos.php");
|
||||||
exit();
|
exit();
|
||||||
} else {
|
} else {
|
||||||
$sql = "SELECT * FROM fs_diasfestivos(null, :dia)";
|
/*$sql = "SELECT * FROM fs_diasfestivos(null, :dia)";
|
||||||
$params = [':dia' => $_POST['diaFestivo']];
|
$params = [':dia' => $_POST['diaFestivo']];
|
||||||
$dia_general = query($sql, $params, false);
|
$dia_general = query($sql, $params, false);
|
||||||
$sql = "SELECT * FROM fs_diasfestivos(null, null, :periodo, :dia)";
|
$sql = "SELECT * FROM fs_diasfestivos(null, null, :periodo, :dia)";
|
||||||
$params = [':periodo' => $periodo, ":dia" => $_POST['diaFestivo']];
|
$params = [':periodo' => $periodo, ":dia" => $_POST['diaFestivo']];
|
||||||
$dia = query($sql, $params, false);
|
$dia = query($sql, $params, false);*/
|
||||||
if (!$dia && !$dia_general) { //no hay repetidos
|
//if (!$dia && !$dia_general) { //no hay repetidos
|
||||||
$sql = "SELECT fi_diasfestivos(:periodo, :dia)";
|
foreach($periodoArr as $periodo){
|
||||||
$id = query($sql, $params, false);
|
$db->querySingle('SELECT fi_diasfestivos({'.implode(",",$fieldName).'}, :dia)', [':dia' => $_POST['diaFestivo']]);
|
||||||
|
/*$sql = "SELECT fi_diasfestivos(:periodo, :dia)";
|
||||||
|
$params = [':periodo' => $periodo, ":dia" => $_POST['diaFestivo']];
|
||||||
|
$id = query($sql, $params, false);*/
|
||||||
|
}
|
||||||
header("Location: ../días_festivos.php");
|
header("Location: ../días_festivos.php");
|
||||||
exit();
|
exit();
|
||||||
} else {
|
|
||||||
|
/*} else {
|
||||||
header("Location: ../días_festivos.php?error=1");
|
header("Location: ../días_festivos.php?error=1");
|
||||||
exit();
|
exit();
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|||||||
135
action/profesor_faltas.php
Normal file
135
action/profesor_faltas.php
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<?
|
||||||
|
require_once "{$_SERVER['DOCUMENT_ROOT']}/class/c_login.php";
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!Login::is_logged()) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
echo json_encode(['error' => 'No se ha iniciado sesión']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
$user = Login::get_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
case 'GET':
|
||||||
|
$facultad = $_GET['facultad'] ?? $user->facultad['facultad_id'] ?? null;
|
||||||
|
$porcentaje = $_GET['porcentaje'] ?? null;
|
||||||
|
$faltas = $_GET['faltas'] ?? null;
|
||||||
|
|
||||||
|
if (!isset($facultad) || !is_numeric($facultad)) {
|
||||||
|
$error = 'No se ha seleccionado una facultad';
|
||||||
|
} else if ((!isset($faltas) || !is_numeric($faltas)) && (!isset($porcentaje) || !is_numeric($porcentaje))) {
|
||||||
|
$error = 'Debe especificar las faltas o el porcentaje';
|
||||||
|
} else if (isset($faltas) && (!is_numeric($faltas) || $faltas <= 0)) {
|
||||||
|
$error = 'Las faltas deben ser un número mayor a 0';
|
||||||
|
} else if (isset($porcentaje) && (!is_numeric($porcentaje) || $porcentaje <= 0)) {
|
||||||
|
$error = 'El porcentaje debe ser un número mayor a 0';
|
||||||
|
} else if (isset($faltas) && isset($porcentaje)) {
|
||||||
|
$error = 'No se puede especificar las faltas y el porcentaje al mismo tiempo';
|
||||||
|
} else if (!isset($facultad) || !is_numeric($facultad)) {
|
||||||
|
$error = 'Debe especificar una facultad';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($error)) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => $error]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
// Initialize the data array
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
// Check if 'profesor' or 'supervisor' is set and prepare the specific part of the SQL query accordingly.
|
||||||
|
if (isset($_GET['profesor']) || isset($_GET['supervisor'])) {
|
||||||
|
|
||||||
|
$condition = isset($_GET['profesor'])
|
||||||
|
? "r.registro_fecha IS NULL AND NOT COALESCE(r.registro_justificada, FALSE)"
|
||||||
|
: "estado_supervisor_id = 2";
|
||||||
|
|
||||||
|
$filter = isset($faltas)
|
||||||
|
? "afcp.faltas >= :faltas"
|
||||||
|
: "afcp.porcentaje >= :porcentaje";
|
||||||
|
|
||||||
|
// Prepare the SQL query with placeholders for parameters
|
||||||
|
$data = array_column($db->query(
|
||||||
|
"WITH fechas AS (
|
||||||
|
SELECT
|
||||||
|
fcc.registro_fecha_ideal,
|
||||||
|
fcc.horario_id,
|
||||||
|
hp.profesor_id
|
||||||
|
FROM fechas_clase_cache fcc
|
||||||
|
JOIN horario_profesor hp USING (horario_id)
|
||||||
|
JOIN horario h USING (horario_id)
|
||||||
|
WHERE (h.PERIODO_ID, h.FACULTAD_ID) = (:periodo_id, :facultad_id) and profesor_id <> 0
|
||||||
|
),
|
||||||
|
asistencia_faltas AS (
|
||||||
|
SELECT
|
||||||
|
f.profesor_id,
|
||||||
|
COUNT(1) AS total,
|
||||||
|
COUNT(1) FILTER (WHERE $condition AND f.registro_fecha_ideal <= current_date) AS faltas
|
||||||
|
FROM fechas f
|
||||||
|
LEFT JOIN registro r USING (registro_fecha_ideal, horario_id, profesor_id)
|
||||||
|
GROUP BY f.profesor_id
|
||||||
|
),
|
||||||
|
asistencia_faltas_con_porcentaje AS (
|
||||||
|
SELECT
|
||||||
|
af.profesor_id,
|
||||||
|
af.faltas,
|
||||||
|
af.total,
|
||||||
|
CASE
|
||||||
|
WHEN af.total > 0 THEN ROUND((af.faltas::NUMERIC / af.total) * 100, 2)
|
||||||
|
ELSE NULL
|
||||||
|
END AS porcentaje
|
||||||
|
FROM asistencia_faltas af
|
||||||
|
WHERE af.faltas > 0
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
json_build_object(
|
||||||
|
'profesor', json_build_object(
|
||||||
|
'profesor_nombre', p.profesor_nombre,
|
||||||
|
'profesor_clave', p.profesor_clave,
|
||||||
|
'profesor_correo', p.profesor_correo
|
||||||
|
),
|
||||||
|
'profesor_id', afcp.profesor_id,
|
||||||
|
'faltas', afcp.faltas,
|
||||||
|
'total', afcp.total,
|
||||||
|
'porcentaje', afcp.porcentaje
|
||||||
|
) AS result_json
|
||||||
|
FROM asistencia_faltas_con_porcentaje afcp
|
||||||
|
JOIN profesor p USING (profesor_id)
|
||||||
|
WHERE $filter
|
||||||
|
ORDER BY afcp.porcentaje DESC",
|
||||||
|
[
|
||||||
|
'periodo_id' => $user->periodo_id,
|
||||||
|
'facultad_id' => $facultad,
|
||||||
|
] + (isset($faltas)
|
||||||
|
? ['faltas' => $faltas]
|
||||||
|
: ['porcentaje' => $porcentaje])
|
||||||
|
), 'result_json');
|
||||||
|
} else {
|
||||||
|
// Send a 400 Bad Request header and an error message in JSON format
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
echo json_encode(['error' => 'Especifique si las faltas son de profesor o supervisor']);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if (empty($data)) {
|
||||||
|
header('HTTP/1.1 404 Not Found');
|
||||||
|
echo json_encode(['error' => 'No se encontraron faltas']);
|
||||||
|
} else {
|
||||||
|
echo json_encode(
|
||||||
|
array_map(fn($item) => json_decode($item), $data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
header('HTTP/1.1 405 Method Not Allowed');
|
||||||
|
echo json_encode(['error' => 'Método no permitido']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'query' => $db->getLastQuery(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -33,26 +33,29 @@ if(isset($_POST["salon"]) && $_POST["salon"] != "")
|
|||||||
|
|
||||||
//--------------
|
//--------------
|
||||||
//Obtiene datos reposición
|
//Obtiene datos reposición
|
||||||
//TODO , SALÓN SALIÓ PENDIENTE Y FALTA REVISAR LISTA DE CORREOS TO
|
$reposicion_rs = $db->querySingle('SELECT h.materia, r.fecha_nueva, r.hora_nueva, r.fecha_clase, h.horario_hora, h.facultad_id, h.facultad, f.clave_dependencia, r.motivo_cancelacion, ta.tipoaula_supervisor , ta.tipoaula_nombre
|
||||||
$reposicion_rs = $db->querySingle('SELECT h.materia, r.fecha_nueva, r.hora_nueva, r.fecha_clase, h.horario_hora, h.facultad_id, h.facultad, f.clave_dependencia, s.salon_id, s.salon_array, r.motivo_cancelacion, ta.tipoaula_supervisor , ta.tipoaula_nombre
|
|
||||||
from reposicion_solicitud r
|
from reposicion_solicitud r
|
||||||
inner join horario_view h on h.horario_id = r.horario_id
|
inner join horario_view h on h.horario_id = r.horario_id
|
||||||
inner join facultad f on f.facultad_id = h.facultad_id
|
inner join facultad f on f.facultad_id = h.facultad_id
|
||||||
inner join tipoaula ta on ta.tipoaula_id = r.tipoaula_id
|
inner join tipoaula ta on ta.tipoaula_id = r.tipoaula_id
|
||||||
left join salon_view s on r.salon_id = s.salon_id
|
|
||||||
where r.reposicion_solicitud_id = :id_repo',
|
where r.reposicion_solicitud_id = :id_repo',
|
||||||
[':id_repo' => $id_repo]
|
[':id_repo' => $id_repo]
|
||||||
);
|
);
|
||||||
|
|
||||||
if($reposicion_rs["salon_id"] == "" || $reposicion_rs["salon_id"] == NULL){
|
//Obtiene datos de salón asignado
|
||||||
|
$salon_rs = $db->querySingle('SELECT s.salon_id, s.salon_array FROM salon_view s where s.salon_id = :id_salon',
|
||||||
|
[':id_salon' => $salon]
|
||||||
|
);
|
||||||
|
if($salon_rs["salon_id"] == "" || $salon_rs["salon_id"] == NULL){
|
||||||
$salon_desc = "Pendiente";
|
$salon_desc = "Pendiente";
|
||||||
}else{
|
}else{
|
||||||
$salon_json = json_decode($reposicion_rs["salon_array"], true);
|
$salon_json = json_decode($salon_rs["salon_array"], true);
|
||||||
if($salon_json[0]== "UNIVERSIDAD LA SALLE"){
|
if($salon_json[0]== "UNIVERSIDAD LA SALLE"){
|
||||||
unset($salon_json[0]);
|
unset($salon_json[0]);
|
||||||
}
|
}
|
||||||
$salon_desc = join(" / ",$salon_json);
|
$salon_desc = join(" / ",$salon_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Obtiene correos
|
//Obtiene correos
|
||||||
$correos_rs = $db->query('SELECT p.profesor_nombre, p.profesor_correo, u.usuario_nombre as jefe_nombre, u.usuario_correo as jefe_correo,
|
$correos_rs = $db->query('SELECT p.profesor_nombre, p.profesor_correo, u.usuario_nombre as jefe_nombre, u.usuario_correo as jefe_correo,
|
||||||
coor.usuario_nombre as coordinador_nombre, coor.usuario_correo as coordinador_correo
|
coor.usuario_nombre as coordinador_nombre, coor.usuario_correo as coordinador_correo
|
||||||
@@ -163,12 +166,12 @@ if($to!= "" && ENVIO_CORREOS){
|
|||||||
</body>';
|
</body>';
|
||||||
|
|
||||||
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
/*if(DB_NAME == "poad_pruebas"){
|
if($_ENV['DB_NAME'] == "paad_pruebas"){
|
||||||
$asunto = "PRUEBAS-".$asunto;
|
$asunto = "PRUEBAS-".$asunto;
|
||||||
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
|
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
|
||||||
}else{*/
|
}else{
|
||||||
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ else
|
|||||||
$comentario = trim(htmlspecialchars($_POST["comentario"], ENT_QUOTES, "UTF-8"));//limpia texto
|
$comentario = trim(htmlspecialchars($_POST["comentario"], ENT_QUOTES, "UTF-8"));//limpia texto
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$duracion_rs = $db->querySingle("select * from duracion where duracion_id = :id", [":id"=>$duracion_id]);
|
$duracion_rs = $db->querySingle("select * from duracion where duracion_id = :id", [":id"=>$duracion_id]);
|
||||||
$duracion_tiempo = $duracion_rs["duracion_interval"];
|
$duracion_tiempo = $duracion_rs["duracion_interval"];
|
||||||
|
|
||||||
@@ -73,6 +74,9 @@ if(intval($dia) != intval($dia_falta)){
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Obtiene materia
|
||||||
|
$materia_rs = $db->querySingle('SELECT materia_nombre from materia where materia_id = :mat',[':mat' => $materia]);
|
||||||
|
|
||||||
//Obtiene correo
|
//Obtiene correo
|
||||||
$correos_rs = $db->querySingle('SELECT coor.usuario_correo, coor.usuario_nombre from usuario coor where rol_id = :rol_coord and facultad_id = (
|
$correos_rs = $db->querySingle('SELECT coor.usuario_correo, coor.usuario_nombre from usuario coor where rol_id = :rol_coord and facultad_id = (
|
||||||
select coalesce(facultad_id,0) from usuario u where u.usuario_id = :id_usr)',[':rol_coord' => COORDINADOR, ':id_usr' => $user->user["id"]]
|
select coalesce(facultad_id,0) from usuario u where u.usuario_id = :id_usr)',[':rol_coord' => COORDINADOR, ':id_usr' => $user->user["id"]]
|
||||||
@@ -98,6 +102,7 @@ if($tipo == 1){//Reposición
|
|||||||
if($traslape){
|
if($traslape){
|
||||||
//print_r($_POST);
|
//print_r($_POST);
|
||||||
//echo "SELECT * from traslape_profesor_reposicion($prof,'".DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')."' , '$hora', $duracion)";
|
//echo "SELECT * from traslape_profesor_reposicion($prof,'".DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')."' , '$hora', $duracion)";
|
||||||
|
|
||||||
header("Location:".$pag."?error=9");
|
header("Location:".$pag."?error=9");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
@@ -110,12 +115,13 @@ if($tipo == 1){//Reposición
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
}catch(Exception $e){
|
}catch(Exception $e){
|
||||||
|
|
||||||
echo $e->getMessage();
|
echo $e->getMessage();
|
||||||
//header("Location: ".$pag."?error=1");
|
//header("Location: ".$pag."?error=1");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
$texto = "<p>Se creó una reposición nueva.</p>";
|
$texto = "<p>Se creó una reposición nueva.</p>";
|
||||||
$texto .= "<p><b>".mb_strtoupper($reposicion_rs["materia"])."</b> del día <b>".$fecha_falta." a las ".$hor." hrs. </b> se propone reponer el <b>".$fecha_new." a las ".$hora." hrs.</b>";
|
$texto .= "<p><b>".mb_strtoupper($materia_rs["materia_nombre"])."</b> del día <b>".$fecha_falta." a las ".$hor." hrs. </b> se propone reponer el <b>".$fecha_new." a las ".$hora." hrs.</b>";
|
||||||
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarla.</p>";
|
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarla.</p>";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -134,11 +140,12 @@ if($tipo == 1){//Reposición
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
}catch(Exception $e){
|
}catch(Exception $e){
|
||||||
|
|
||||||
header("Location: ".$pag."?error=1");
|
header("Location: ".$pag."?error=1");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
$texto = "<p>Se creó un cambio de salón nuevo.</p>";
|
$texto = "<p>Se creó un cambio de salón nuevo.</p>";
|
||||||
$texto .= "<p><b>".mb_strtoupper($reposicion_rs["materia"])."</b> del día <b>".$fecha_falta." a las ".$hora." hrs. </b> se propone reponer el <b>".$fecha_nueva." a las ".$hora_nueva." hrs.</b>";
|
$texto .= "<p><b>".mb_strtoupper($materia_rs["materia_nombre"])."</b> del día <b>".$fecha_falta." a las ".$hora." hrs. </b> se propone reponer el <b>".$fecha_nueva." a las ".$hora_nueva." hrs.</b>";
|
||||||
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarlo.</p>";
|
$texto .= "<p>Ingresa al <a href='https://paad.lci.ulsa.mx'>sistema PAAD</a> para autorizarlo.</p>";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -159,14 +166,14 @@ if($to!= "" && ENVIO_CORREOS){
|
|||||||
</body>';
|
</body>';
|
||||||
|
|
||||||
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
require_once('../include/phpmailer/PHPMailerAutoload.php');
|
||||||
/*if(DB_NAME == "poad_pruebas"){
|
if($_ENV['DB_NAME'] == "paad_pruebas"){
|
||||||
$asunto = "PRUEBAS-".$asunto;
|
$asunto = "PRUEBAS-".$asunto;
|
||||||
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
|
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
|
||||||
}else{*/
|
}else{
|
||||||
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
Mailer::enviarCorreo($to, $asunto, $texto, true);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header("Location: ".$pag."?ok=0");
|
|
||||||
exit();
|
exit();
|
||||||
|
header("Location: ".$pag."?ok=0");
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
class Mailer{
|
class Mailer{
|
||||||
private const FROM = "academia@lasalle.mx";
|
private const FROM = "academia@lasalle.mx";
|
||||||
private const FROM_NAME = "Vicerrectoría Académica";
|
private const FROM_NAME = "Vicerrectoría Académica";
|
||||||
private const FROM_PASS = "Foy25193";
|
private const FROM_PASS = "4c4d3m14S3gur4##";//Foy25193
|
||||||
private const FOOTER = "<p style='margin-top:5em; color:#aaa;font-style:italics'><small>Este es un correo automatizado, esta cuenta no recibe correos.<small></p>";
|
private const FOOTER = "<p style='margin-top:5em; color:#aaa;font-style:italics'><small>Este es un correo automatizado, esta cuenta no recibe correos.<small></p>";
|
||||||
//private $lista_to, $asunto, $texto;
|
//private $lista_to, $asunto, $texto;
|
||||||
|
|
||||||
@@ -50,24 +50,40 @@ class Mailer{
|
|||||||
}else{//cadena de texto separada por ;
|
}else{//cadena de texto separada por ;
|
||||||
if(strpos($lista_to, ";")!==false){
|
if(strpos($lista_to, ";")!==false){
|
||||||
$toArr = explode(";", $lista_to);
|
$toArr = explode(";", $lista_to);
|
||||||
|
foreach($toArr as $correo){
|
||||||
|
if(trim($correo)!=""){
|
||||||
|
if($bcc)
|
||||||
|
$mail->addBCC($correo);
|
||||||
|
else
|
||||||
|
$mail->AddAddress($correo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}elseif(strpos($lista_to, ",")!==false){
|
}elseif(strpos($lista_to, ",")!==false){
|
||||||
$toArr = explode(",", $lista_to);
|
$toArr = explode(",", $lista_to);
|
||||||
|
foreach($toArr as $correo){
|
||||||
|
if(trim($correo)!=""){
|
||||||
|
if($bcc)
|
||||||
|
$mail->addBCC($correo);
|
||||||
|
else
|
||||||
|
$mail->AddAddress($correo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
echo "Cadena de correos inválida";
|
if(trim($lista_to)!=""){
|
||||||
return false;
|
|
||||||
}
|
|
||||||
foreach($toArr as $correo){
|
|
||||||
if(trim($correo)!=""){
|
|
||||||
if($bcc)
|
if($bcc)
|
||||||
$mail->addBCC($correo);
|
$mail->addBCC($lista_to);
|
||||||
else
|
else
|
||||||
$mail->AddAddress($correo);
|
$mail->AddAddress($lista_to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//Success
|
//Success
|
||||||
if ($mail->Send()) {
|
if ($mail->Send()) {
|
||||||
return true;
|
return true;
|
||||||
|
}else{
|
||||||
|
echo "Error al enviar correo";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}catch(phpmailerException $e){
|
}catch(phpmailerException $e){
|
||||||
echo $mail->ErrorInfo;
|
echo $mail->ErrorInfo;
|
||||||
|
|||||||
142
export/faltas_excel.php
Normal file
142
export/faltas_excel.php
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$fecha = date('d_m_Y');
|
||||||
|
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
header("Content-Disposition: attachment;filename=horario_$fecha.xlsx");
|
||||||
|
header("Cache-Control: max-age=0");
|
||||||
|
|
||||||
|
require_once "../vendor/autoload.php";
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||||
|
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
|
||||||
|
// Image settings
|
||||||
|
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
|
||||||
|
$drawing->setName('La Salle')
|
||||||
|
->setDescription('La Salle')
|
||||||
|
->setPath('../imagenes/logo.png')
|
||||||
|
->setCoordinates('B1')
|
||||||
|
->setHeight(100)
|
||||||
|
->setOffsetX(10)
|
||||||
|
->setWorksheet($spreadsheet->getActiveSheet());
|
||||||
|
|
||||||
|
$json = file_get_contents('php://input');
|
||||||
|
$data = json_decode($json, true);
|
||||||
|
|
||||||
|
empty($data) and die(json_encode(['error' => 'No se recibieron datos', 'data' => $data]));
|
||||||
|
|
||||||
|
$data_excel = array(
|
||||||
|
"CLAVE" => 'profesor_clave',
|
||||||
|
"PROFESOR" => 'profesor_nombre',
|
||||||
|
"CORREO" => 'profesor_correo',
|
||||||
|
"FALTAS" => 'faltas',
|
||||||
|
"TOTAL" => 'total',
|
||||||
|
"PORCENTAJE" => 'porcentaje',
|
||||||
|
); // Same as before
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ROW = 6;
|
||||||
|
// Merge cells from A1 to C+ ROW
|
||||||
|
$sheet->mergeCells('A1:B' . (ROW - 1));
|
||||||
|
// Merge cells from D1 to size of $data_excel + 1
|
||||||
|
$sheet->mergeCells('C1:' . chr(65 + count($data_excel) - 1) . (ROW - 1));
|
||||||
|
|
||||||
|
// Set the title in D1 Sistema de Auditoría de Asistencia
|
||||||
|
$sheet->setCellValue('C1', 'Sistema de Auditoría de Asistencia');
|
||||||
|
$sheet->getStyle('C1')->applyFromArray([
|
||||||
|
'font' => [
|
||||||
|
'bold' => true,
|
||||||
|
'size' => 30,
|
||||||
|
'name' => 'Indivisa Text Sans',
|
||||||
|
'color' => ['argb' => '001d68'],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$lastColumnLetter = chr(65 + count($data_excel) - 1);
|
||||||
|
$headers_range = 'A' . ROW . ':' . $lastColumnLetter . ROW;
|
||||||
|
|
||||||
|
$keys = array_keys($data_excel);
|
||||||
|
array_walk($keys, function ($key, $index) use ($sheet) {
|
||||||
|
$sheet->setCellValue(chr(65 + $index) . ROW, $key);
|
||||||
|
});
|
||||||
|
// Apply the header styles
|
||||||
|
$sheet->getStyle($headers_range)->applyFromArray([
|
||||||
|
'font' => [
|
||||||
|
'bold' => true,
|
||||||
|
'size' => 15,
|
||||||
|
'name' => 'Indivisa Text Sans',
|
||||||
|
'color' => ['argb' => Color::COLOR_WHITE],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['argb' => '001d68'],
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// set filters
|
||||||
|
$sheet->setAutoFilter($headers_range);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Styles that are common for all rows can be set outside the loop
|
||||||
|
|
||||||
|
const DEFAULT_FONT = [
|
||||||
|
'size' => 12,
|
||||||
|
'name' => 'Indivisa Text Sans',
|
||||||
|
'color' => ['argb' => '001d68']
|
||||||
|
];
|
||||||
|
|
||||||
|
const DEFAULT_STYLE = [
|
||||||
|
'alignment' => [
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
'wrapText' => true,
|
||||||
|
],
|
||||||
|
'font' => DEFAULT_FONT,
|
||||||
|
'borders' => [
|
||||||
|
'outline' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['argb' => Color::COLOR_WHITE],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($data as $index => $registro) {
|
||||||
|
$pair = $index % 2 == 0;
|
||||||
|
$cellRange = 'A' . (ROW + $index + 1) . ':' . $lastColumnLetter . (ROW + $index + 1);
|
||||||
|
$styleArray = DEFAULT_STYLE;
|
||||||
|
$styleArray['fill'] = [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['argb' => $pair ? 'd4d9dd' : 'f6f7f8'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$sheet->getStyle($cellRange)->applyFromArray($styleArray);
|
||||||
|
$values = array_values($data_excel);
|
||||||
|
array_walk($values, function ($row, $column_index) use ($sheet, $index, $registro) {
|
||||||
|
$cellLocation = chr(65 + $column_index) . (ROW + $index + 1);
|
||||||
|
$sheet->setCellValue($cellLocation, $registro[$row]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($sheet->getColumnIterator() as $column) {
|
||||||
|
$sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
|
||||||
|
$writer->save('php://output');
|
||||||
275
faltas.php
Normal file
275
faltas.php
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Auditoría de faltas</title>
|
||||||
|
<?php
|
||||||
|
include 'import/html_css_files.php';
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/jquery-ui.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
|
||||||
|
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<?
|
||||||
|
$redirect = $_SERVER['PHP_SELF'];
|
||||||
|
include "import/html_header.php";
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
html_header(
|
||||||
|
"Faltas",
|
||||||
|
"Sistema de gestión de checador",
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!$user->periodo_id) { ?>
|
||||||
|
<script defer src="js/jquery.min.js"></script>
|
||||||
|
<script src="js/bootstrap/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<div class="modal" id="seleccionar-periodo" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-dialog-centered modal-xl">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title">Seleccionar periodo</h2>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body container">
|
||||||
|
<? include 'import/periodo.php' ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$('#seleccionar-periodo').modal({
|
||||||
|
backdrop: 'static',
|
||||||
|
keyboard: false,
|
||||||
|
});
|
||||||
|
$('#seleccionar-periodo').modal('show');
|
||||||
|
</script>
|
||||||
|
<? exit;
|
||||||
|
} ?>
|
||||||
|
|
||||||
|
<main class="container-fluid px-4 mt-4" id="app" v-cloak @vue:mounted="mounted" style="min-height: 60vh;"
|
||||||
|
v-scope="">
|
||||||
|
<?php include "import/periodo.php" ?>
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-box marco">
|
||||||
|
<? if (!$user->facultad['facultad_id']) { ?>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="dlFacultad" class="col-4 col-form-label" id="facultad">Facultad</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div id="dlFacultad" class="datalist datalist-select mb-1 w-100">
|
||||||
|
<div class="datalist-input">
|
||||||
|
Selecciona una facultad
|
||||||
|
</div>
|
||||||
|
<span class="icono ing-buscar"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<li class="datalist-option d-none" data-id="-1">
|
||||||
|
Selecciona una facultad
|
||||||
|
</li>
|
||||||
|
<li class="datalist-option" v-for="facultad in facultades"
|
||||||
|
:key="facultad.facultad_id" :data-id="facultad.facultad_id"
|
||||||
|
@click="filter.facultad = facultad.facultad_id;">
|
||||||
|
(<small> {{facultad.clave_dependencia}} </small>) {{ facultad.facultad_nombre }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="facultad_id" name="id">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<? } ?>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="profesor" class="col-4 col-form-label">Profesor</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="form-row justify-content-around align-items-center">
|
||||||
|
<input id="profesor" name="profesor" class="form-control col-11 mr-1 px-2"
|
||||||
|
placeholder="Seleccione una profesor" list="dlProfesor" v-model="filter.profesor">
|
||||||
|
<button type="button" class="btn btn-outline-danger btn-sm form-control col ml-auto"
|
||||||
|
@click="filter.profesor = '';">
|
||||||
|
<i class="ing-borrar"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<datalist id="dlProfesor">
|
||||||
|
<option v-for="profesor in profesores" :key="profesor.profesor_id"
|
||||||
|
:value="`(${profesor.profesor_clave}) ${profesor.profesor_nombre}`">
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row" v-scope ="{
|
||||||
|
input_faltas: true,
|
||||||
|
}">
|
||||||
|
<label for="porcentaje" class="col-4 col-form-label" id="facultad">
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<span class="mr-5" :class="{'text-muted': input_faltas}">Número</span>
|
||||||
|
<input type="checkbox" class="custom-control-input" id="faltas_porcentaje"
|
||||||
|
v-model="input_faltas" @change="<? if ($user->facultad['facultad_id']) { ?> filter.facultad = <?= $user->facultad['facultad_id'] ?>; <? } ?> filter.porcentaje = input_faltas ? 10 : 0; filter.faltas = input_faltas ? 0 : 1">
|
||||||
|
<label class="custom-control-label" for="faltas_porcentaje"
|
||||||
|
:class="{'text-muted': !input_faltas}">
|
||||||
|
Porcentaje
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
de faltas
|
||||||
|
</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div id="porcentaje" class="datalist datalist-select mb-1 w-100" V-if="input_faltas">
|
||||||
|
<div class="datalist-input">
|
||||||
|
Selecciona una porcentaje
|
||||||
|
</div>
|
||||||
|
<span class="icono ing-buscar"></span>
|
||||||
|
<ul style="display:none">
|
||||||
|
<li class="datalist-option d-none" data-id="-1">
|
||||||
|
Selecciona un porcentaje
|
||||||
|
</li>
|
||||||
|
<li class="datalist-option"
|
||||||
|
v-for="porcentaje in Array.from({length: 5}, (_, i) => (i + 1) * 10)"
|
||||||
|
:key="facultad.facultad_id" :data-id="facultad.facultad_id"
|
||||||
|
<? if ($user->facultad['facultad_id']) { ?>
|
||||||
|
@click="filter.porcentaje = porcentaje; filter.facultad = <?= $user->facultad['facultad_id'] ?>;"
|
||||||
|
<? } else { ?>
|
||||||
|
@click="filter.porcentaje = porcentaje;"
|
||||||
|
<? } ?> >
|
||||||
|
{{ porcentaje }}%
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<input type="hidden" id="facultad_id" name="id">
|
||||||
|
</div>
|
||||||
|
<input type="number" class="form-control" v-model="filter.faltas" v-else
|
||||||
|
@change="" min="1" max="100" step="1"
|
||||||
|
<? if ($user->facultad['facultad_id']) { ?>
|
||||||
|
@click="filter.facultad = <?= $user->facultad['facultad_id'] ?>"
|
||||||
|
<? } ?>
|
||||||
|
placeholder="Número de faltas">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="porcentaje" class="col-4 col-form-label" id="facultad">Faltas</label>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="form-row justify-content-center align-items-center text-center">
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="tipoFaltas"
|
||||||
|
v-model="filter.tipoFaltas" @change="">
|
||||||
|
<label class="custom-control-label" for="tipoFaltas"
|
||||||
|
:class="{'text-muted': !filter.tipoFaltas}">
|
||||||
|
Faltas del {{ filter.tipoFaltas ? 'Supervisor' : 'Profesor' }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row justify-content-center align-items-center">
|
||||||
|
<div class="col-auto">
|
||||||
|
<button type="button" class="btn btn-success" @click="toExcel()" :disabled="!faltas.length" :class="{'disabled': !faltas.length}">
|
||||||
|
<i class=" ing-descarga"></i>
|
||||||
|
Exportar a Excel</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<button type="button" class="btn btn-primary" @click="refresh()" :disabled="(filter.facultad <= 0) || (filter.faltas <= 0 && filter.porcentaje <= 0)" :class="{'disabled': !filter.facultad || !filter.faltas && !filter.porcentaje}">
|
||||||
|
<i class=" ing-buscar"></i>
|
||||||
|
Buscar faltas
|
||||||
|
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table-responsive marco" v-if="faltas.length > 0" v-scope="{orderBy: [
|
||||||
|
{column: 'Profesor', order: 'asc'},
|
||||||
|
{column: 'Faltas', order: 'desc'},
|
||||||
|
{column: 'Total', order: 'desc'},
|
||||||
|
{column: 'Porcentaje', order: 'desc'},
|
||||||
|
]}">
|
||||||
|
<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" v-for="column in orderBy">
|
||||||
|
{{ column.column }}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="falta in faltas.filter(({profesor}) => filter.profesor ? (profesor.profesor_nombre.toLowerCase().includes(filter.profesor.toLowerCase()) || filter.profesor.toLowerCase().includes(`(${profesor.profesor_clave}) ${profesor.profesor_nombre}`.toLowerCase())) : true)"
|
||||||
|
:key="`flata-${falta.profesor_id}`">
|
||||||
|
<td class="align-middle px-2">
|
||||||
|
<strong>{{ falta.profesor.profesor_clave }}</strong>
|
||||||
|
{{ falta.profesor.profesor_nombre }}
|
||||||
|
</td>
|
||||||
|
<td class="align-middle px-2 text-center">
|
||||||
|
{{ falta.faltas }}
|
||||||
|
</td>
|
||||||
|
<td class="align-middle px-2 text-center">
|
||||||
|
{{ falta.total }}
|
||||||
|
</td>
|
||||||
|
<td class="align-middle px-2 text-center">
|
||||||
|
{{ falta.porcentaje }}%
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="modal" tabindex="-1" id="cargando" data-backdrop="static" data-keyboard="false">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Cargando datos...</h4>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-body container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<span class="spinner-border spinner-border-lg"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal" tabindex="-1" id="mensaje">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">{{mensaje.titulo}}</h4>
|
||||||
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
{{mensaje.texto}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- <script src=" js/datalist.js"></script> -->
|
||||||
|
<script src="js/datepicker-es.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
|
||||||
|
<script src="js/faltas.js?<?= rand(0, 2) ?>" type="module"></script>
|
||||||
|
<script src="js/scrollables.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
84
js/faltas.js
Normal file
84
js/faltas.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module';
|
||||||
|
const filter = reactive({
|
||||||
|
facultad: -1,
|
||||||
|
profesor: '',
|
||||||
|
porcentaje: 0,
|
||||||
|
faltas: 0,
|
||||||
|
tipoFaltas: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
filter,
|
||||||
|
facultades: [],
|
||||||
|
profesores: [],
|
||||||
|
faltas: [],
|
||||||
|
mensaje: {
|
||||||
|
titulo: '',
|
||||||
|
texto: '',
|
||||||
|
},
|
||||||
|
async refresh() {
|
||||||
|
if (filter.facultad == -1 || (filter.porcentaje < 10 && filter.faltas < 1)) {
|
||||||
|
console.log('Facultad: ', filter.facultad, 'Porcentaje: ', filter.porcentaje, 'Faltas: ', filter.faltas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#cargando').modal('show');
|
||||||
|
try {
|
||||||
|
|
||||||
|
this.faltas = await fetch(`action/profesor_faltas.php?facultad=${this.filter.facultad}&${this.filter.tipoFaltas ? 'supervisor' : 'profesor'}&${this.filter.faltas > 0 ? 'faltas' : 'porcentaje'}=${this.filter.faltas > 0 ? this.filter.faltas : this.filter.porcentaje}`).then(res => res.json());
|
||||||
|
if (this.faltas.error) {
|
||||||
|
$('.modal#mensaje').modal('show');
|
||||||
|
this.mensaje.titulo = 'Información';
|
||||||
|
this.mensaje.texto = this.faltas.error;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$('.modal#mensaje').modal('show');
|
||||||
|
this.mensaje.titulo = 'Error';
|
||||||
|
this.mensaje.texto = 'No se pudo cargar los datos';
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
$('#cargando').modal('hide');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async toExcel() {
|
||||||
|
if (filter.facultad == -1 || filter.porcentaje < 10) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#cargando').modal('show');
|
||||||
|
try {
|
||||||
|
const response = await fetch(`export/faltas_excel.php`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(this.faltas.map(falta => ({
|
||||||
|
'profesor_clave': falta.profesor.profesor_clave,
|
||||||
|
'profesor_correo': falta.profesor.profesor_correo,
|
||||||
|
'profesor_nombre': falta.profesor.profesor_nombre,
|
||||||
|
'faltas': falta.faltas,
|
||||||
|
'porcentaje': `${falta.porcentaje}%`,
|
||||||
|
'total': falta.total,
|
||||||
|
}))),
|
||||||
|
})
|
||||||
|
|
||||||
|
const blob = await response.blob();
|
||||||
|
window.saveAs(blob, `faltas_${this.facultades.find(facultad => facultad.facultad_id == filter.facultad).facultad_nombre}_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
||||||
|
} catch (error) {
|
||||||
|
$('.modal#mensaje').modal('show');
|
||||||
|
this.mensaje.titulo = 'Error';
|
||||||
|
this.mensaje.texto = 'No se pudo cargar los datos';
|
||||||
|
console.log('Error: ', error);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
$('#cargando').modal('hide');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
try {
|
||||||
|
this.facultades = await fetch('action/action_facultad.php').then(res => res.json());
|
||||||
|
this.profesores = await fetch('action/action_profesor.php').then(res => res.json());
|
||||||
|
} catch (error) {
|
||||||
|
$('.modal#mensaje').modal('show');
|
||||||
|
this.mensaje.titulo = 'Error';
|
||||||
|
this.mensaje.texto = 'No se pudo cargar los datos';
|
||||||
|
console.log('Error: ', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).mount('#app');
|
||||||
38
ts/faltas.ts
Normal file
38
ts/faltas.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module';
|
||||||
|
// define that $ has type any
|
||||||
|
declare const $: any;
|
||||||
|
|
||||||
|
const filter = reactive({
|
||||||
|
facultad: -1,
|
||||||
|
profesor: '',
|
||||||
|
porcentaje: 0
|
||||||
|
});
|
||||||
|
const app = createApp({
|
||||||
|
filter,
|
||||||
|
facultades: [],
|
||||||
|
profesores: [],
|
||||||
|
|
||||||
|
faltas: [],
|
||||||
|
openModal() {
|
||||||
|
const modal = document.getElementById('cargando');
|
||||||
|
$(modal).modal('show');
|
||||||
|
},
|
||||||
|
closeModal() {
|
||||||
|
const modal = document.getElementById('cargando');
|
||||||
|
$(modal).modal('hide');
|
||||||
|
},
|
||||||
|
|
||||||
|
async refresh() {
|
||||||
|
if(filter.facultad == -1 || filter.porcentaje < 10) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.openModal();
|
||||||
|
this.faltas = await fetch(`action/profesor_faltas.php?facultad=${this.filter.facultad}&profesor=${this.filter.profesor}&porcentaje=${this.filter.porcentaje}`).then(res => res.json());
|
||||||
|
this.closeModal();
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
this.facultades = await fetch('action/action_facultad.php').then(res => res.json());
|
||||||
|
this.profesores = await fetch('action/action_profesor.php').then(res => res.json());
|
||||||
|
}
|
||||||
|
}).mount('#app');
|
||||||
Reference in New Issue
Block a user