-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- SIU-GUARANI 3 -- Version 3.0.0 -- Function: f_copiar_mesa_examen -- -- Copia una mesa de examen desde un turno de examen a otro turno de examen en un llamado -- * Datos de la mesa de examen, instancias, propuestas y planes -- * Docentes de la mesa. -- -- Recibe: -- f_copiar_mesa_examen(integer,integer, integer) -- 1. ID de la mesa de examen origen (sga_mesas_examen.mesa_examen) -- 2. ID del turno de examen destino -- 3. Metodo de asignacion de la fecha y hora de la mesa -- 1 = Respetar día de la semana: Esta opción implicará que, en la copia, se respete el día de la semana de la mesa de orígen siempre y cuando no sea un feriado, si es un feriado se pasa al próximo día habil. -- 2 = Respetar orden del dia en el llamado: Esta opción implicará que, en la copia, se respete el numero de día en que está la mesa en el llamado de origen (por ejemplo si una mesa está en el primer día del llamado, se copiará alprimer dia del llamado de destino) siempre que sea un dia habil, en caso de no serlo (feriado, domingo,...) se creará el próximo día habil. -- 3 = Respetar dia por Cátedra Esta opción implicará que se cree la mesa en el dia de la semana definido por la Cátedra para la actividad de la mesa de examen a crear, ademas del horario de inicio y finalización (en el caso que ese ingresado). -- 4 = Respetar dia por Actividad: Esta opción implicará que se cree la mesa en el dia de la semana definido por la actividad de la mesa de examen a crear, ademas del horario de inicio y finalización (en el caso que ese ingresado). -- -- Retorna: Retorna un registro por cada llamado (con los datos de la mesa-llamado), con observaciones en el caso que la mesa no se copio tal cual estaba en el origen. -- - Conjunto de datos de tipo: type_mesa_examen_llamado -- -- Ejemplo: Codigo Retorno: 0- Mesa examen copiada sin cambios / 1 - Mesa de examen no fue copiada con observaciones / 2- Mesa de Examen copiada con observaciones -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- DROP FUNCTION f_copiar_mesa_examen (integer, integer, integer); CREATE OR REPLACE FUNCTION f_copiar_mesa_examen( _mesa_origen integer, _turno_destino integer, _metodo_asign_fecha integer) RETURNS SETOF type_mesa_examen_llamado AS $BODY$ DECLARE _mesa_examen_nueva INTEGER; nombre_mesa_examen VARCHAR(50); llamado_mesa_origen INTEGER; llamado_mesa_nuevo INTEGER; _catedra INTEGER; _estado_catedra char(1); _nombre_catedra TEXT; _fecha_desde DATE; _fecha_hasta DATE; _fecha_mesa DATE; _hora_inicio time; _def_hora_inicio time; _hora_fin time; _dia_examen varchar(10); _dia_llamado integer; llo smallint; lld smallint; _existe_llamado_destino boolean; _llamado_destino integer; _llamado_fecha_inicio DATE; _llamado_fecha_fin DATE; _resultado smallint; _elemento INTEGER; cnt SMALLINT; copia_con_error boolean; _observaciones text; _actividad text; _codigo_actividad varchar(10); _nombre_mesa_examen text; cur_subc record; cur_docentes record; cur_eval record; llamados_origen record; llamados_dest record; cur_retorno type_mesa_examen_llamado; -- para retornar datos de la mesa-llamado. BEGIN copia_con_error := false; -- Recupero datos de la mesa de examen SELECT '(' || sga_elementos.codigo || ') ' || sga_elementos.nombre, sga_mesas_examen.nombre, sga_mesas_examen.elemento, sga_mesas_examen.catedra, sga_elementos.codigo, sga_catedras.estado, sga_catedras.nombre INTO _actividad, _nombre_mesa_examen, _elemento, _catedra, _codigo_actividad, _estado_catedra, _nombre_catedra FROM sga_mesas_examen LEFT JOIN sga_catedras ON sga_mesas_examen.catedra = sga_catedras.catedra, sga_elementos WHERE sga_elementos.elemento = sga_mesas_examen.elemento AND sga_mesas_examen.mesa_examen = _mesa_origen; -- Verifico si la catedra esta activa IF _catedra IS NOT NULL AND _estado_catedra <> 'A' THEN copia_con_error := TRUE; -- (1) mesa_examen no copiada SELECT 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'La cátedra esta dada de baja' INTO cur_retorno; RETURN NEXT cur_retorno; RETURN; -- Salgo END IF; -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- Inserto la mesa_examen -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INSERT INTO sga_mesas_examen (nombre, elemento, catedra, ubicacion) SELECT nombre, elemento, catedra, ubicacion FROM sga_mesas_examen WHERE mesa_examen = _mesa_origen; -- Recupero el Serial de la mesa_examen _mesa_examen_nueva := (SELECT currval('sga_mesas_examen_seq')); -- Modalidad de Cursada. INSERT INTO sga_mesas_examen_modalidad (mesa_examen, modalidad) SELECT _mesa_examen_nueva, modalidad FROM sga_mesas_examen_modalidad WHERE mesa_examen = _mesa_origen; -- Propuestas y Planes de la mesa_examen INSERT INTO sga_mesas_examen_propuestas (mesa_examen, propuesta, plan) SELECT _mesa_examen_nueva, propuesta, plan FROM sga_mesas_examen_propuestas WHERE mesa_examen = _mesa_origen; -- Instancias de la mesa_examen INSERT INTO sga_mesas_examen_instancias (mesa_examen, instancia, escala_nota) SELECT _mesa_examen_nueva, instancia, escala_nota FROM sga_mesas_examen_instancias WHERE mesa_examen = _mesa_origen; -- Valores default _dia_examen := NULL; _hora_inicio := NULL; _hora_fin := NULL; _def_hora_inicio := time '08:00:00'; -- Asignación de Fecha y Hora del Examen. IF _metodo_asign_fecha = 3 THEN -- 3 = Respetar dia por Cátedra Esta opción implicará que se cree la mesa en el dia de la semana definido por la Cátedra para la actividad de la mesa de examen a crear, ademas del horario de inicio y finalización (en el caso que ese ingresado). -- Fecha definida en la cátedra de la materia. IF _catedra IS NOT NULL THEN SELECT dia_examen, hora_inicio_examen, hora_fin_examen INTO _dia_examen, _hora_inicio, _hora_fin FROM sga_catedras_actividades WHERE sga_catedras_actividades.catedra = _catedra AND sga_elementos.elemento = _elemento; END IF; ELSEIF _metodo_asign_fecha = 4 THEN -- 3 = Respetar dia por Actividad: Esta opción implicará que se cree la mesa en el dia de la semana definido por la actividad de la mesa de examen a crear, ademas del horario de inicio y finalización (en el caso que ese ingresado). SELECT dia_examen, hora_inicio_examen, hora_fin_examen INTO _dia_examen, _hora_inicio, _hora_fin FROM sga_elementos_atrib WHERE sga_elementos_atrib.elemento = _elemento; END IF; -- ---------------------------------------------------------------------------------- -- Recorro cada uno de los llamados en los que se encuentra la mesa de examen origen. -- ---------------------------------------------------------------------------------- llo := 0; FOR llamados_origen IN SELECT sga_llamados_mesa.llamado as llamado, sga_llamados_mesa.llamado_mesa as llamado_mesa, sga_llamados_mesa.entidad as entidad, sga_llamados_mesa.fecha as fecha, sga_llamados_mesa.hora_inicio as hora_inicio, sga_llamados_mesa.hora_finalizacion as hora_finalizacion, sga_periodos.fecha_inicio as fecha_inicio, sga_periodos.fecha_fin as fecha_fin FROM sga_llamados_mesa, sga_llamados_turno, sga_periodos WHERE sga_llamados_mesa.mesa_examen = _mesa_origen AND sga_llamados_mesa.llamado = sga_llamados_turno.llamado AND sga_periodos.periodo = sga_llamados_turno.periodo ORDER BY sga_llamados_mesa.fecha ASC LOOP llo := llo + 1; lld := 0; _llamado_destino := NULL; _llamado_fecha_inicio := NULL; _llamado_fecha_fin := NULL; _existe_llamado_destino := false; -- Recorro los llamados del turno destino para buscar el llamado correspondiente al llamado del turno origen actual. FOR llamados_dest IN SELECT llamado, nombre, fecha_inicio, fecha_fin FROM sga_llamados_turno, sga_periodos WHERE sga_llamados_turno.periodo = sga_periodos.periodo AND sga_llamados_turno.turno_examen = _turno_destino ORDER BY fecha_inicio ASC LOOP lld := lld + 1; IF llo = lld THEN _existe_llamado_destino := true; -- Encontre el mismo llamado en el turno de examen destino _llamado_destino := llamados_dest.llamado; _llamado_fecha_inicio := llamados_dest.fecha_inicio; _llamado_fecha_fin := llamados_dest.fecha_fin; EXIT; -- Salgo del loop. END IF; END LOOP; -- llamado turno destino IF not _existe_llamado_destino THEN -- No se encontro el llamado del turno destino que corresponde con el turno origen. EXIT; -- Salgo del loop de los llamados del turno origen. END IF; -- Genero la Fecha, hora de inicio y finalización de la mesa de examen. _fecha_mesa := NULL; IF _metodo_asign_fecha = 1 THEN -- Recupero el dia de la semana de la mesa en el llamado origen y asigno mismo horario de inicio y finalizacion del examen. _dia_examen := f_diadelasemana(llamados_origen.fecha::date, 1::smallint); -- date_part('dow', llamados_origen.fecha); _hora_inicio := llamados_origen.hora_inicio; _hora_fin := llamados_origen.hora_finalizacion; ELSEIF _metodo_asign_fecha = 2 THEN -- Respetar orden del dia en el llamado: Esta opción implicará que, en la copia, se respete el numero de día en que está la mesa en el llamado de origen --(por ejemplo si una mesa está en el primer día del llamado, se copiará alprimer dia del llamado de destino). _dia_llamado := llamados_origen.fecha - llamados_origen.fecha_inicio; _fecha_mesa := llamados_dest.fecha_inicio + _dia_llamado; -- Se verifica si la fecha de examen calculada entra en el período del llamado destino, de otra forma se asigna null para que luego se setee el valor por defecto. IF (_fecha_mesa > llamados_dest.fecha_fin) THEN _fecha_mesa := NULL; END IF; _hora_inicio := llamados_origen.hora_inicio; _hora_fin := llamados_origen.hora_finalizacion; END IF; -- Metodos de asignacion de fecha, hora de inicio y fin IF (_metodo_asign_fecha = 1 OR _metodo_asign_fecha = 3 OR _metodo_asign_fecha = 4) THEN IF _dia_examen IS NOT NULL THEN -- Mínima fecha del llamado correspondiente al dia de la semana definido para la actividad _fecha_mesa := f_minfechadia(_llamado_fecha_inicio, _llamado_fecha_fin, _dia_examen); END IF; END IF; IF _fecha_mesa IS NULL THEN _fecha_mesa := _llamado_fecha_inicio; END IF; IF _hora_inicio IS NULL THEN _hora_inicio := _def_hora_inicio; END IF; -- Asocio la Mesa de Examen en el Llamado del Turno Destino INSERT INTO sga_llamados_mesa (llamado, mesa_examen, fecha, hora_inicio, hora_finalizacion) VALUES (_llamado_destino, _mesa_examen_nueva, _fecha_mesa, _hora_inicio, _hora_fin); llamado_mesa_nuevo := (SELECT currval('sga_llamados_mesa_seq')); -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- Evaluaciones de la mesa_examen asociadas a cada llamado del Turno destino (no las automáticas) -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INSERT INTO sga_evaluaciones (nombre, entidad, evaluacion_tipo, visible_al_alumno, fecha, hora_inicio, hora_fin, escala_nota, estado) SELECT e.nombre, llmd.entidad, e.evaluacion_tipo, e.visible_al_alumno, llmd.fecha, llmd.hora_inicio, llmd.hora_finalizacion, e.escala_nota, 'A' FROM sga_evaluaciones as e, sga_llamados_mesa as llmd, sga_evaluaciones_tipos WHERE e.entidad = llamados_origen.entidad AND sga_evaluaciones_tipos.evaluacion_tipo = e.evaluacion_tipo AND sga_evaluaciones_tipos.automatica = 'N' AND llmd.llamado_mesa = llamado_mesa_nuevo; -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- Docentes de la mesa_examen asignados a cada llamado del Turno destino -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FOR cur_docentes IN SELECT dm.docente, dm.rol, sga_docentes.legajo, sga_docentes.estado, mdp_personas.apellido, mdp_personas.nombres FROM sga_docentes_mesa_llamado as dm, sga_docentes, mdp_personas WHERE dm.llamado_mesa = llamados_origen.llamado_mesa AND sga_docentes.docente = dm.docente AND mdp_personas.persona = sga_docentes.persona LOOP -- Si el docente esta dado de baja, entonces no copio el docente. IF cur_docentes.estado <> 'A' THEN copia_con_error := TRUE; _observaciones := COALESCE(_observaciones || ' - ', NULL); _observaciones := COALESCE(_observaciones || ' - ', '') || 'El docente (' || cur_docentes.legajo || ') ' || cur_docentes.apellido || ' ' || cur_docentes.nombres || ' no se copió en la mesa porque esta dado de baja'; END IF; -- Inserto el docente para la mesa de examen y llamado INSERT INTO sga_docentes_mesa_llamado (llamado_mesa, docente, rol) VALUES (llamado_mesa_nuevo, cur_docentes.docente, cur_docentes.rol); END LOOP; -- Docentes de la mesa en el llamado. IF NOT copia_con_error THEN _resultado := 0; ELSE _resultado := 2; END IF; -- Retorno los datos de la mesa en el llamado que fue copiado. SELECT _resultado, _mesa_examen_nueva, _llamado_destino, llamados_dest.nombre, llamado_mesa_nuevo, to_char(_fecha_mesa, 'dd/mm/yyyy'), to_char(_hora_inicio, 'hh:mm'), to_char(_hora_fin, 'hh:mm'), _observaciones INTO cur_retorno; RETURN NEXT cur_retorno; -- Limpio variables. IF _metodo_asign_fecha = 1 OR _metodo_asign_fecha = 2 THEN _fecha_mesa := NULL; _hora_inicio := NULL; _hora_fin := NULL; END IF; END LOOP; -- Llamados del turno origen donde se encuentra la mesa de examen a copiar -- Salgo de la funcion. RETURN; END; $BODY$ LANGUAGE 'plpgsql' VOLATILE; -- ++++++++++++++++++++++++++++++ Fin Function f_copiar_mesa_examen(integer, integer, integer) ++++++++++++++++ -- REVOKE EXECUTE ON FUNCTION f_copiar_mesa_examen (integer, integer, integer) FROM public; GRANT EXECUTE ON FUNCTION f_copiar_mesa_examen (integer, integer, integer) to public; /* select * from f_copiar_mesa_examen(1, 1202, 1); select * from f_copiar_mesa_examen(28542, 16, 3); select * from vw_mesas_examen where turno_examen = 1201 select * from sga_turnos_examen where turno_examen in (1201, 1202) select * from sga_llamados_turno where turno_examen in (1201, 1202) select * from sga_periodos_lectivos pl, sga_periodos p where pl.periodo = p.periodo select * from sga_mesas_examen where mesa_examen = 28541; select * from sga_mesas_examen_propuestas where mesa_examen = 28541; select * from sga_mesas_examen_instancias where mesa_examen = 28541; select * from sga_docentes_mesa_examen where mesa_examen = 28541; select * from sga_ _examenes where mesa_examen = 28541; select * from sga_mesas_examen where mesa_examen = 38740; select * from sga_mesas_examen_propuestas where mesa_examen = 38740; select * from sga_mesas_examen_instancias where mesa_examen = 38740; select * from sga_docentes_mesa_examen where mesa_examen = 38740; select * from sga_submesa_examenes where mesa_examen = 38740; */