Carga de horarios
This commit is contained in:
parent
44d19d97d1
commit
93eb18cd6d
6
API.md
6
API.md
@ -52,8 +52,8 @@
|
|||||||
# Carga de horarios
|
# Carga de horarios
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// HTTP GET
|
// HTTP POST
|
||||||
// Url: /horarios?cursos=...
|
// Url: /horarios
|
||||||
|
|
||||||
// El frontend envia una lista de cursos, de los cuales recuperar sus datos
|
// El frontend envia una lista de cursos, de los cuales recuperar sus datos
|
||||||
{
|
{
|
||||||
@ -74,13 +74,13 @@
|
|||||||
{
|
{
|
||||||
id_laboratorio: number,
|
id_laboratorio: number,
|
||||||
id_curso: number,
|
id_curso: number,
|
||||||
id_horario: number,
|
|
||||||
grupo: string,
|
grupo: string,
|
||||||
docente: string,
|
docente: string,
|
||||||
// Array de objetos de la entidad Horario
|
// Array de objetos de la entidad Horario
|
||||||
horario: [
|
horario: [
|
||||||
{
|
{
|
||||||
id_horario: number,
|
id_horario: number,
|
||||||
|
id_laboratorio: number,
|
||||||
dia: string,
|
dia: string,
|
||||||
hora_inicio: string,
|
hora_inicio: string,
|
||||||
hora_fin: string,
|
hora_fin: string,
|
||||||
|
@ -1,143 +1,52 @@
|
|||||||
|
|
||||||
// Exclusivo de un unico dia
|
// Exclusivo de un unico dia
|
||||||
|
import { GrupoDia, TableInput } from "../src/Views/SistemasMovil/Table";
|
||||||
|
import { generarMapaCeldas, MapaCeldas } from "../src/Views/SistemasMovil/mapaCeldas";
|
||||||
|
|
||||||
type Input = {
|
type Input = {
|
||||||
horaInicio: number,
|
offsetVertical: number,
|
||||||
nroHoras: number,
|
nroHoras: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Output = {
|
|
||||||
horaInicio: number,
|
|
||||||
nroHoras: number,
|
|
||||||
offset: number, // 0, 1, 2
|
|
||||||
fraccion: number, // por cuanto dividir la celda. 1, 2, 3, ...
|
|
||||||
}
|
|
||||||
|
|
||||||
class MapaCeldas {
|
|
||||||
// Almacena referencias a input
|
|
||||||
private mapa: Map<number, Map<number, null>> = new Map();
|
|
||||||
|
|
||||||
private disponible(nroFila: number, nroColumna: number): boolean {
|
|
||||||
if (!this.mapa.has(nroFila)) return true;
|
|
||||||
|
|
||||||
const fila = this.mapa.get(nroFila)!;
|
|
||||||
|
|
||||||
return fila.has(nroColumna) === false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private obtenerFilaOCrear(nro: number): Map<number, null> {
|
|
||||||
if (!this.mapa.has(nro)) {
|
|
||||||
const m = new Map<number, null>();
|
|
||||||
this.mapa.set(nro, m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.mapa.get(nro)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Devuelve el offset
|
|
||||||
public solicitar(inicio: number, cantidad: number): number {
|
|
||||||
const filas = [];
|
|
||||||
for (let i = 0; i < cantidad; i += 1) filas.push(inicio + i);
|
|
||||||
|
|
||||||
for (let offsetActual = 0; offsetActual < 8; offsetActual += 1) {
|
|
||||||
let todasCeldasDisponibles = true;
|
|
||||||
for (const fila of filas) {
|
|
||||||
if (!this.disponible(fila, offsetActual)) {
|
|
||||||
todasCeldasDisponibles = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (todasCeldasDisponibles) {
|
|
||||||
// Crear estas celdas y almacenar
|
|
||||||
filas.forEach((nroFila) => {
|
|
||||||
const fila = this.obtenerFilaOCrear(nroFila);
|
|
||||||
fila.set(offsetActual, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Devolver nro de offset
|
|
||||||
return offsetActual;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error("Limite de celdas alcanzado");
|
|
||||||
}
|
|
||||||
|
|
||||||
public generarFraccion(nroFila: number, nroColumna: number, cantidad: number): number {
|
|
||||||
let fraccionActual = 1;
|
|
||||||
for (let i = 0; i < cantidad; i += 1) {
|
|
||||||
const nroFilaActual = nroFila + i;
|
|
||||||
const filaActual = this.mapa.get(nroFilaActual)!;
|
|
||||||
const numeroColumnas = filaActual.size;
|
|
||||||
if (numeroColumnas > fraccionActual) {
|
|
||||||
fraccionActual = numeroColumnas;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fraccionActual;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function generarMapaCeldas(entrada: Readonly<Array<Input>>): Array<Output> {
|
|
||||||
const mapa = new MapaCeldas();
|
|
||||||
const salida: Array<Output> = [];
|
|
||||||
|
|
||||||
// Obtener los offsets de cada curso
|
|
||||||
for (const input of entrada) {
|
|
||||||
const offset = mapa.solicitar(input.horaInicio, input.nroHoras);
|
|
||||||
salida.push({
|
|
||||||
...input,
|
|
||||||
offset,
|
|
||||||
fraccion: -1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generar las fracciones de cada curso
|
|
||||||
for (const output of salida) {
|
|
||||||
output.fraccion = mapa.generarFraccion(output.horaInicio, output.offset, output.nroHoras);
|
|
||||||
}
|
|
||||||
|
|
||||||
return salida;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("generarMapaCeldas", () => {
|
describe("generarMapaCeldas", () => {
|
||||||
it("vacio si input es vacio", () => {
|
it("vacio si input es vacio", () => {
|
||||||
const input: Array<Input> = [];
|
const input: Array<GrupoDia> = [];
|
||||||
const output = generarMapaCeldas(input);
|
const output = generarMapaCeldas(input);
|
||||||
expect(output.length).toBe(0);
|
expect(output.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("funciona con 1 curso", () => {
|
it("funciona con 1 curso", () => {
|
||||||
const input: Array<Input> = [
|
const input: Array<any> = [
|
||||||
{
|
{
|
||||||
horaInicio: 0,
|
offsetVertical: 0,
|
||||||
nroHoras: 2,
|
nroHoras: 2,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const output = generarMapaCeldas(input)[0];
|
const output = generarMapaCeldas(input)[0];
|
||||||
expect(output).not.toBeUndefined();
|
expect(output).not.toBeUndefined();
|
||||||
expect(output.offset).toBe(0);
|
expect(output.offsetHorizontal).toBe(0);
|
||||||
expect(output.fraccion).toBe(1);
|
expect(output.fraccion).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("funciona con 2 cursos", () => {
|
it("funciona con 2 cursos", () => {
|
||||||
const input: Array<Input> = [
|
const input: Array<any> = [
|
||||||
{
|
{
|
||||||
horaInicio: 0,
|
offsetVertical: 0,
|
||||||
nroHoras: 2,
|
nroHoras: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
horaInicio: 1,
|
offsetVertical: 1,
|
||||||
nroHoras: 3,
|
nroHoras: 3,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const output1 = generarMapaCeldas(input)[0];
|
const output1 = generarMapaCeldas(input)[0];
|
||||||
expect(output1.offset).toBe(0);
|
expect(output1.offsetHorizontal).toBe(0);
|
||||||
expect(output1.fraccion).toBe(2);
|
expect(output1.fraccion).toBe(2);
|
||||||
|
|
||||||
const output2 = generarMapaCeldas(input)[1];
|
const output2 = generarMapaCeldas(input)[1];
|
||||||
expect(output2.offset).toBe(1);
|
expect(output2.offsetHorizontal).toBe(1);
|
||||||
expect(output2.fraccion).toBe(2);
|
expect(output2.fraccion).toBe(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
175
src/API/CargaHorarios.ts
Normal file
175
src/API/CargaHorarios.ts
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
// HTTP POST
|
||||||
|
// Url: /horarios
|
||||||
|
|
||||||
|
// El frontend envia una lista de cursos, de los cuales recuperar sus datos
|
||||||
|
{
|
||||||
|
cursos: Array<number> // Un array de id_curso
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend responde con los cursos especificados y sus horarios
|
||||||
|
[
|
||||||
|
// Cada objeto dentro del array sera un Curso
|
||||||
|
{
|
||||||
|
id_curso: number,
|
||||||
|
id_datos_carrera: any, // Opcional
|
||||||
|
nombre_curso: string,
|
||||||
|
curso_anio: number | string,
|
||||||
|
abreviado: string,
|
||||||
|
// Un array de objetos, estos objetos son de la entidad Laboratorio
|
||||||
|
laboratorios: [
|
||||||
|
{
|
||||||
|
id_laboratorio: number,
|
||||||
|
id_curso: number,
|
||||||
|
grupo: string,
|
||||||
|
docente: string,
|
||||||
|
// Array de objetos de la entidad Horario
|
||||||
|
horario: [
|
||||||
|
{
|
||||||
|
id_horario: number,
|
||||||
|
dia: string,
|
||||||
|
hora_inicio: string,
|
||||||
|
hora_fin: string,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import { SERVER_PATH } from "../Store";
|
||||||
|
|
||||||
|
export type Horario = {
|
||||||
|
id_horario: number,
|
||||||
|
id_laboratorio: number,
|
||||||
|
dia: string,
|
||||||
|
hora_inicio: string,
|
||||||
|
hora_fin: string,
|
||||||
|
}
|
||||||
|
export type Laboratorio = {
|
||||||
|
id_laboratorio: number,
|
||||||
|
id_curso: number,
|
||||||
|
grupo: string,
|
||||||
|
docente: string,
|
||||||
|
// Array de objetos de la entidad Horario
|
||||||
|
horario: Array<Horario>
|
||||||
|
}
|
||||||
|
export type CursoCompleto = {
|
||||||
|
id_curso: number,
|
||||||
|
nombre_curso: string,
|
||||||
|
curso_anio: number | string,
|
||||||
|
abreviado: string,
|
||||||
|
// Un array de objetos, estos objetos son de la entidad Laboratorio
|
||||||
|
laboratorios: Array<Laboratorio>
|
||||||
|
}
|
||||||
|
|
||||||
|
type InputData = {
|
||||||
|
cursos: Array<number>
|
||||||
|
}
|
||||||
|
export type ListaCursosCompleto = Array<CursoCompleto>
|
||||||
|
|
||||||
|
type GetHorariosFn = (_: InputData) => Promise<ListaCursosCompleto>
|
||||||
|
|
||||||
|
export const getHorarios: GetHorariosFn = async(data) => {
|
||||||
|
const response = await fetch(`${SERVER_PATH}/horarios`, {
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
return await response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getHorariosMock: GetHorariosFn = async(_) => {
|
||||||
|
const c1: CursoCompleto = {
|
||||||
|
id_curso: 0,
|
||||||
|
nombre_curso: "Gestion de Sistemas y Tecnologias de Informacion",
|
||||||
|
curso_anio: "5to",
|
||||||
|
abreviado: "GSTI",
|
||||||
|
laboratorios: [
|
||||||
|
{
|
||||||
|
id_laboratorio: 0,
|
||||||
|
id_curso: 0,
|
||||||
|
grupo: "A",
|
||||||
|
docente: "Luis Rocha",
|
||||||
|
horario: [
|
||||||
|
{
|
||||||
|
id_horario: 0,
|
||||||
|
id_laboratorio: 0,
|
||||||
|
hora_inicio: "1830",
|
||||||
|
hora_fin: "1920",
|
||||||
|
dia: "Jueves",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id_horario: 1,
|
||||||
|
id_laboratorio: 0,
|
||||||
|
hora_inicio: "1550",
|
||||||
|
hora_fin: "1740",
|
||||||
|
dia: "Viernes",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id_laboratorio: 1,
|
||||||
|
id_curso: 0,
|
||||||
|
grupo: "B",
|
||||||
|
docente: "Luis Rocha",
|
||||||
|
horario: [
|
||||||
|
{
|
||||||
|
id_horario: 2,
|
||||||
|
id_laboratorio: 1,
|
||||||
|
hora_inicio: "0700",
|
||||||
|
hora_fin: "0850",
|
||||||
|
dia: "Lunes",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id_horario: 3,
|
||||||
|
id_laboratorio: 1,
|
||||||
|
hora_inicio: "1400",
|
||||||
|
hora_fin: "1640",
|
||||||
|
dia: "Miercoles",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const c2: CursoCompleto = {
|
||||||
|
id_curso: 1,
|
||||||
|
nombre_curso: "Plataformas Emergentes",
|
||||||
|
curso_anio: "5to",
|
||||||
|
abreviado: "PE",
|
||||||
|
laboratorios: [
|
||||||
|
{
|
||||||
|
id_laboratorio: 2,
|
||||||
|
id_curso: 1,
|
||||||
|
grupo: "A",
|
||||||
|
docente: "Diego Iquira",
|
||||||
|
horario: [
|
||||||
|
{
|
||||||
|
id_horario: 4,
|
||||||
|
id_laboratorio: 2,
|
||||||
|
hora_inicio: "0850",
|
||||||
|
hora_fin: "0940",
|
||||||
|
dia: "Jueves",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id_laboratorio: 3,
|
||||||
|
id_curso: 1,
|
||||||
|
grupo: "B",
|
||||||
|
docente: "Diego Iquira",
|
||||||
|
horario: [
|
||||||
|
{
|
||||||
|
id_horario: 5,
|
||||||
|
id_laboratorio: 3,
|
||||||
|
hora_inicio: "1740",
|
||||||
|
hora_fin: "1830",
|
||||||
|
dia: "Martes",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
return [c1, c2];
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user