-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- SIU-GUARANI 3
-- Version 3.0.0
-- Function: f_promedio
--
-- Retorna el promedio de las actividades realizadas por el alumno en la propuesta
--  * Promedio a una fecha.
--  * Actividades de la propuesta o actividades de un certificado.
--  * Promedio con aplazos o sin aplazos
--  
-- Recibe:  f_promedios(integer, date, integer, char)
--   1. Alumno
--   2. Fecha (promedio a una fecha)
--   3. Certificado
--   4. Con Aplazos . S = Con Aplazos / N - Sin Aplazos
--
-- Retorna: 
--      1. Promedio.  numeric(8,3)
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

-- DROP FUNCTION f_promedio(integer, date, integer, char);
CREATE OR REPLACE FUNCTION f_promedio(_alumno Integer, _fecha Date, _certificado Integer, _con_aplazos char(1))
  RETURNS numeric(8,3) AS 
$BODY$
DECLARE 
  _promedio numeric(8,3);
  _cantidad integer;      
  _cantidad_plan integer;      
  _persona  integer;
  _plan_version_alumno integer;
  _total_notas decimal(10,3);
  _fecha_promedio date;
BEGIN
  
  _cantidad := 0;
  _promedio := 0;
  
  -- Si la fecha es nula le paso la fecha actual.
  IF _fecha IS NULL THEN 
    _fecha_promedio := CURRENT_DATE;
  ELSE  
    _fecha_promedio := _fecha;
  END IF;
  
  -- Recupero id de la persona y version de plan de estudios en el que se encuentra el alumno.
  SELECT persona, plan_version
    INTO _persona, _plan_version_alumno
    FROM sga_alumnos 
   WHERE alumno = _alumno;

   -- Actividades del alumno de la version actual del alumno
   CREATE TEMP TABLE temp_actividades (elemento integer, escala_nota integer, nota varchar(10), resultado char(1));

  -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  -- Recupero actividades:
  --  * Aprobadas/reprobadas de la version actual del alumno
  --  * Con fecha menor o igual a la fecha pasada por parametro.
  --  * Solo actividades que son promediables
  -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  INSERT INTO temp_actividades (elemento, escala_nota, nota, resultado)
   SELECT vw_hist_academica.elemento, 
          vw_hist_academica.escala_nota, 
          vw_hist_academica.nota, 
          vw_hist_academica.resultado
     FROM sga_alumnos,
          vw_hist_academica    
     WHERE sga_alumnos.persona = _persona
     AND vw_hist_academica.alumno = sga_alumnos.alumno
     AND vw_hist_academica.elemento IN (SELECT vw_elementos_plan.elemento 
                                          FROM vw_elementos_plan,
                                               sga_elementos_plan
                                         WHERE vw_elementos_plan.plan_version = _plan_version_alumno
                                           AND sga_elementos_plan.elemento_plan = vw_elementos_plan.elemento_plan
                                           AND sga_elementos_plan.promediable = 'S')
     AND vw_hist_academica.fecha <= _fecha_promedio;
   
  -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  -- Promedio General en la Propuesta (con/sin aplazos)
  -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  IF _certificado IS NULL THEN
  
    /*
    -- Recupero cantidad de actividades del Plan de estudios..
    -- Que pasa con las NO OBLIGATORIAS???
    SELECT COUNT(*) INTO _cantidad_plan
      FROM vw_elementos_plan 
      WHERE plan_version = _plan_version_alumno;
    */  
    
    -- Recupero el total de notas y la cantidad de examenes/promociones/equivalencias consideradas en el calculo.  
    SELECT SUM(e.valor_numerico), COUNT(*) 
      INTO _total_notas, _cantidad
      FROM temp_actividades as t,
           sga_escalas_notas_det as e
      WHERE ((_con_aplazos = 'S' AND t.resultado IN ('A','R')) OR
             (_con_aplazos = 'N' AND t.resultado = 'A')
            )
        AND t.nota IS NOT NULL
        AND e.escala_nota = t.escala_nota
        AND e.nota = t.nota
        AND e.valor_numerico IS NOT NULL;
      
      -- Promedio
      _promedio := _total_notas / _cantidad;
      
  END IF;
  
  -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  -- Recupero actividades del certificado
  -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  IF _certificado IS NOT NULL THEN
  END IF;
  
  
  -- Borro tabla temporal.
  DROP TABLE temp_actividades;
  
  -- Retorno el promedio
  RETURN _promedio;
    
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
-- ++++++++++++++++++++++++++++++ Fin Function f_promedio ++++++++++++++++

-- REVOKE EXECUTE ON FUNCTION f_promedio (integer, date, integer, char) FROM public;
GRANT EXECUTE ON FUNCTION f_promedio (integer, date, integer, char) to public;

