From da22d3c86b90436eba9bc8489a6b511437fa8209 Mon Sep 17 00:00:00 2001
From: Alejandro Rosales
Date: Mon, 27 Nov 2023 15:13:44 +0000
Subject: [PATCH] New things
---
action/action_diasfestivos_insert.php | 33 ++--
action/profesor_faltas.php | 135 +++++++++++++
action/reposicion_autoriza.php | 19 +-
action/reposicion_insert.php | 19 +-
class/mailer.php | 32 ++-
export/faltas_excel.php | 142 +++++++++++++
faltas.php | 275 ++++++++++++++++++++++++++
js/faltas.js | 84 ++++++++
ts/faltas.ts | 38 ++++
9 files changed, 742 insertions(+), 35 deletions(-)
create mode 100644 action/profesor_faltas.php
create mode 100644 export/faltas_excel.php
create mode 100644 faltas.php
create mode 100644 js/faltas.js
create mode 100644 ts/faltas.ts
diff --git a/action/action_diasfestivos_insert.php b/action/action_diasfestivos_insert.php
index 632c404..7ff0bce 100644
--- a/action/action_diasfestivos_insert.php
+++ b/action/action_diasfestivos_insert.php
@@ -12,11 +12,10 @@ require_once "../include/bd_pdo.php";
global $pdo;
//print_r($_POST);
if (!isset($_POST['periodo']) || count($_POST["periodo"])==0) {
- //header("Location: ../días_festivos.php?error=1");
- echo "Error no hay periodo";
+ header("Location: ../días_festivos.php?error=0");
exit();
}
-$periodo = $_POST['periodo'];
+$periodoArr = $_POST['periodo'];
if (isset($_POST['rango'])) {
$diaInicio = new DateTime(date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo']))));
@@ -24,27 +23,35 @@ if (isset($_POST['rango'])) {
$cantidad = $diaFin->diff($diaInicio);
$date = date("Y-m-d", strtotime(str_replace("/", "-", $_POST['diaFestivo'])));
for ($dias = 0; $dias <= $cantidad->days; $dias++) {
- $sql = "SELECT fi_diasfestivos(:periodo, :dia)";
- $params = [':periodo' => $periodo, ':dia' => $date];
- query($sql, $params, false);
+
+ $db->querySingle('SELECT fi_diasfestivos({'.implode(",",$fieldName).'}, :dia)', [':dia' => $date]);
+ /*$sql = "SELECT fi_diasfestivos(:periodo, :dia)";
+ $params = [':periodo' => $periodo, ':dia' => $date];
+ query($sql, $params, false);*/
+
$date = date("Y-m-d", strtotime($date . "+ 1 days"));
}
header("Location: ../días_festivos.php");
exit();
} else {
- $sql = "SELECT * FROM fs_diasfestivos(null, :dia)";
+ /*$sql = "SELECT * FROM fs_diasfestivos(null, :dia)";
$params = [':dia' => $_POST['diaFestivo']];
$dia_general = query($sql, $params, false);
$sql = "SELECT * FROM fs_diasfestivos(null, null, :periodo, :dia)";
$params = [':periodo' => $periodo, ":dia" => $_POST['diaFestivo']];
- $dia = query($sql, $params, false);
- if (!$dia && !$dia_general) { //no hay repetidos
- $sql = "SELECT fi_diasfestivos(:periodo, :dia)";
- $id = query($sql, $params, false);
+ $dia = query($sql, $params, false);*/
+ //if (!$dia && !$dia_general) { //no hay repetidos
+ foreach($periodoArr as $periodo){
+ $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");
exit();
- } else {
+
+ /*} else {
header("Location: ../días_festivos.php?error=1");
exit();
- }
+ }*/
}
diff --git a/action/profesor_faltas.php b/action/profesor_faltas.php
new file mode 100644
index 0000000..500dcdc
--- /dev/null
+++ b/action/profesor_faltas.php
@@ -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(),
+ ]);
+}
diff --git a/action/reposicion_autoriza.php b/action/reposicion_autoriza.php
index 67ce10d..2c91177 100644
--- a/action/reposicion_autoriza.php
+++ b/action/reposicion_autoriza.php
@@ -33,26 +33,29 @@ if(isset($_POST["salon"]) && $_POST["salon"] != "")
//--------------
//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, s.salon_id, s.salon_array, 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, r.motivo_cancelacion, ta.tipoaula_supervisor , ta.tipoaula_nombre
from reposicion_solicitud r
inner join horario_view h on h.horario_id = r.horario_id
inner join facultad f on f.facultad_id = h.facultad_id
inner join tipoaula ta on ta.tipoaula_id = r.tipoaula_id
- left join salon_view s on r.salon_id = s.salon_id
where r.reposicion_solicitud_id = :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";
}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"){
unset($salon_json[0]);
}
$salon_desc = join(" / ",$salon_json);
}
+
//Obtiene correos
$correos_rs = $db->query('SELECT p.profesor_nombre, p.profesor_correo, u.usuario_nombre as jefe_nombre, u.usuario_correo as jefe_correo,
coor.usuario_nombre as coordinador_nombre, coor.usuario_correo as coordinador_correo
@@ -163,12 +166,12 @@ if($to!= "" && ENVIO_CORREOS){
+
+ $redirect = $_SERVER['PHP_SELF'];
+ include "import/html_header.php";
+ global $user;
+
+ html_header(
+ "Faltas",
+ "Sistema de gestión de checador",
+ );
+
+
+
+ if (!$user->periodo_id) { ?>
+
+
+
+
+
+
+
+
+ include 'import/periodo.php' ?>
+
+
+
+
+
+ exit;
+ } ?>
+
+
+
+
+
+
+
+
+
+
+ |
+ {{ column.column }}
+ |
+
+
+
+
+ |
+ {{ falta.profesor.profesor_clave }}
+ {{ falta.profesor.profesor_nombre }}
+ |
+
+ {{ falta.faltas }}
+ |
+
+ {{ falta.total }}
+ |
+
+ {{ falta.porcentaje }}%
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{mensaje.texto}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
require_once('../include/phpmailer/PHPMailerAutoload.php');
- /*if(DB_NAME == "poad_pruebas"){
+ if($_ENV['DB_NAME'] == "paad_pruebas"){
$asunto = "PRUEBAS-".$asunto;
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
- }else{*/
+ }else{
Mailer::enviarCorreo($to, $asunto, $texto, true);
- //}
+ }
}
/*
diff --git a/action/reposicion_insert.php b/action/reposicion_insert.php
index 0a74451..9b1b940 100644
--- a/action/reposicion_insert.php
+++ b/action/reposicion_insert.php
@@ -39,6 +39,7 @@ else
$comentario = trim(htmlspecialchars($_POST["comentario"], ENT_QUOTES, "UTF-8"));//limpia texto
+
$duracion_rs = $db->querySingle("select * from duracion where duracion_id = :id", [":id"=>$duracion_id]);
$duracion_tiempo = $duracion_rs["duracion_interval"];
@@ -73,6 +74,9 @@ if(intval($dia) != intval($dia_falta)){
exit();
}
+//Obtiene materia
+$materia_rs = $db->querySingle('SELECT materia_nombre from materia where materia_id = :mat',[':mat' => $materia]);
+
//Obtiene correo
$correos_rs = $db->querySingle('SELECT coor.usuario_correo, coor.usuario_nombre from usuario coor where rol_id = :rol_coord and facultad_id = (
select coalesce(facultad_id,0) from usuario u where u.usuario_id = :id_usr)',[':rol_coord' => COORDINADOR, ':id_usr' => $user->user["id"]]
@@ -98,6 +102,7 @@ if($tipo == 1){//Reposición
if($traslape){
//print_r($_POST);
//echo "SELECT * from traslape_profesor_reposicion($prof,'".DateTime::createFromFormat('d/m/Y', $fecha)->format('Y-m-d')."' , '$hora', $duracion)";
+
header("Location:".$pag."?error=9");
exit();
}
@@ -110,12 +115,13 @@ if($tipo == 1){//Reposición
]
);
}catch(Exception $e){
+
echo $e->getMessage();
//header("Location: ".$pag."?error=1");
exit();
}
$texto = "
Se creó una reposición nueva.
";
- $texto .= "
".mb_strtoupper($reposicion_rs["materia"])." del día ".$fecha_falta." a las ".$hor." hrs. se propone reponer el ".$fecha_new." a las ".$hora." hrs.";
+ $texto .= "
".mb_strtoupper($materia_rs["materia_nombre"])." del día ".$fecha_falta." a las ".$hor." hrs. se propone reponer el ".$fecha_new." a las ".$hora." hrs.";
$texto .= "
Ingresa al sistema PAAD para autorizarla.
";
/*
@@ -134,11 +140,12 @@ if($tipo == 1){//Reposición
]
);
}catch(Exception $e){
+
header("Location: ".$pag."?error=1");
exit();
}
$texto = "
Se creó un cambio de salón nuevo.
";
- $texto .= "
".mb_strtoupper($reposicion_rs["materia"])." del día ".$fecha_falta." a las ".$hora." hrs. se propone reponer el ".$fecha_nueva." a las ".$hora_nueva." hrs.";
+ $texto .= "
".mb_strtoupper($materia_rs["materia_nombre"])." del día ".$fecha_falta." a las ".$hora." hrs. se propone reponer el ".$fecha_nueva." a las ".$hora_nueva." hrs.";
$texto .= "
Ingresa al sistema PAAD para autorizarlo.
";
/*
@@ -159,14 +166,14 @@ if($to!= "" && ENVIO_CORREOS){
';
require_once('../include/phpmailer/PHPMailerAutoload.php');
- /*if(DB_NAME == "poad_pruebas"){
+ if($_ENV['DB_NAME'] == "paad_pruebas"){
$asunto = "PRUEBAS-".$asunto;
Mailer::enviarCorreo("alejandro.lara@lasalle.mx", $asunto, $texto, true);
- }else{*/
+ }else{
Mailer::enviarCorreo($to, $asunto, $texto, true);
- //}
+ }
}
-header("Location: ".$pag."?ok=0");
exit();
+header("Location: ".$pag."?ok=0");
?>
diff --git a/class/mailer.php b/class/mailer.php
index 382fdd2..c12d802 100644
--- a/class/mailer.php
+++ b/class/mailer.php
@@ -5,7 +5,7 @@
class Mailer{
private const FROM = "academia@lasalle.mx";
private const FROM_NAME = "Vicerrectoría Académica";
- private const FROM_PASS = "Foy25193";
+ private const FROM_PASS = "4c4d3m14S3gur4##";//Foy25193
private const FOOTER = "
Este es un correo automatizado, esta cuenta no recibe correos.
";
//private $lista_to, $asunto, $texto;
@@ -50,24 +50,40 @@ class Mailer{
}else{//cadena de texto separada por ;
if(strpos($lista_to, ";")!==false){
$toArr = explode(";", $lista_to);
+ foreach($toArr as $correo){
+ if(trim($correo)!=""){
+ if($bcc)
+ $mail->addBCC($correo);
+ else
+ $mail->AddAddress($correo);
+ }
+ }
}elseif(strpos($lista_to, ",")!==false){
$toArr = explode(",", $lista_to);
+ foreach($toArr as $correo){
+ if(trim($correo)!=""){
+ if($bcc)
+ $mail->addBCC($correo);
+ else
+ $mail->AddAddress($correo);
+ }
+ }
}else{
- echo "Cadena de correos inválida";
- return false;
- }
- foreach($toArr as $correo){
- if(trim($correo)!=""){
+ if(trim($lista_to)!=""){
if($bcc)
- $mail->addBCC($correo);
+ $mail->addBCC($lista_to);
else
- $mail->AddAddress($correo);
+ $mail->AddAddress($lista_to);
}
}
+
}
//Success
if ($mail->Send()) {
return true;
+ }else{
+ echo "Error al enviar correo";
+ return false;
}
}catch(phpmailerException $e){
echo $mail->ErrorInfo;
diff --git a/export/faltas_excel.php b/export/faltas_excel.php
new file mode 100644
index 0000000..6b360e8
--- /dev/null
+++ b/export/faltas_excel.php
@@ -0,0 +1,142 @@
+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');
\ No newline at end of file
diff --git a/faltas.php b/faltas.php
new file mode 100644
index 0000000..bc2b6c5
--- /dev/null
+++ b/faltas.php
@@ -0,0 +1,275 @@
+
+
+
+
+
+
+
Auditoría de faltas
+
+
+
+
+
+
+
+
+
+
+