public ActionResult Configuration(Alumno alumno, FormCollection form)
        {
            int cont = 0;
            IRepositorio<AlumnoMaterium> repositorioAlumnoMateria = new AlumnoMateriumRepositorio();
            IList<AlumnoMaterium> listAlumnoMateria = repositorioAlumnoMateria.GetAll();

            IRepositorio<PromedioFactor> repositorioPromedioFactor = new PromedioFactorRepositorio();
            IList<PromedioFactor> listPromedioFactor = repositorioPromedioFactor.GetAll();

            IRepositorio<Actividad> repositorioActividad = new ActividadRepositorio();

            IRepositorio<Materium> repositorioMaterium = new MateriumRepositorio();
            IList<Materium> listMaterium = repositorioMaterium.GetAll();

            IRepositorio<HorarioPreferencia> repositorioHorarioPreferencia = new HorarioPreferenciaRepositorio();

            IRepositorio<ClaseEvaluacion> repositorioHorarioClase = new HorarioClaseRepositorio();
            var listCronograma = repositorioHorarioClase.GetAll().Where(alum => alum.Cedula == alumno.Cedula);

            var listActividades = repositorioActividad.GetAll().Where(a => a.Periodo.CompareTo(_periodoActual) == 0);

            var misMaterias = (from d in listCronograma
                               from c in listActividades
                               where c.Tipo.CompareTo("Clase") == 0 &&
                                     d.IdActividad == c.IdActividad
                               select c.IdMateria).Distinct();

            var misEvaluaciones = (from d in listCronograma
                                   from c in listActividades
                                   where c.Tipo.CompareTo("Evaluacion") == 0 &&
                                         d.IdActividad == c.IdActividad
                                   select c).ToList();

            var mayorCredito = (from mat in listMaterium
                                select mat.Creditos).Max();

            alumno.Materiums = new List<Materium>();
            foreach (var materia in misMaterias)
            {
                Materium mat = repositorioMaterium.GetById(materia);
                alumno.Materiums.Add(mat);
            }
            var strings = form.GetValues("selrate");
            if (strings != null)
            {
                if ((alumno.Materiums.Count + 15) == strings.Count())
                {
                    int contador = 0;
                    int sum = 0;
                    foreach (var value in strings)
                    {
                        if (contador > 14)
                        {
                            var alumnoMateria = (from mat in listAlumnoMateria
                                                 where mat.IdMateria == alumno.Materiums.ElementAt(cont).IdMateria &&
                                                       mat.Cedula == alumno.Cedula
                                                 select mat).First();
                            alumnoMateria.Preferencia = Convert.ToInt32(value);
                            var porcentajePref = (alumnoMateria.Preferencia * 100) / 5.0;

                            var promedio = (from prom in listPromedioFactor
                                            where
                                                prom.IdMateria == alumno.Materiums.ElementAt(cont).IdMateria &&
                                                prom.Factor.CompareTo("Promedio") == 0
                                            select prom.Promedio).First();

                            var porcentajeProm = (double)(((20 - promedio) * 100) / 20);

                            var uc = alumno.Materiums.ElementAt(cont).Creditos;

                            var porcentajeUC = (uc * 100) / mayorCredito;

                            alumnoMateria.Prioridad = (porcentajePref + porcentajeProm + porcentajeUC) / 3;

                            //Se toma en cuenta las notas obtenidas en las evaluaciones
                            foreach (var miEvaluacion in misEvaluaciones)
                            {
                                var miNota = (from cE in listCronograma
                                              where cE.IdActividad == miEvaluacion.IdActividad
                                              select cE.Nota).First();
                                if (miNota != 0.0)
                                {
                                    const int x1 = 10;
                                    const int y1 = 0;
                                    const int x2 = 20;
                                    var y2 = -alumnoMateria.Prioridad * (miEvaluacion.Ponderacion / 100.00);
                                    var pendiente1 = (y2 - y1) / (x2 - x1);
                                    var factorM = (miNota * pendiente1) - y2;
                                    alumnoMateria.Prioridad += factorM;
                                }
                            }

                            repositorioAlumnoMateria.Update(alumnoMateria);

                            cont++;
                        }
                        else
                        {
                            int hora = contador + 7;
                            var horaIni = new DateTime(2012, 01, 01, hora, 0, 0);
                            var horaFin = new DateTime(2012, 01, 01, hora + 1, 0, 0);

                            var listHorarioPref = repositorioHorarioPreferencia.GetAll();
                            var horarioPreferencia = (from hp in listHorarioPref
                                                      where hp.Cedula == alumno.Cedula &
                                                            hp.HoraInicio.CompareTo(horaIni) == 0 &
                                                            hp.HoraFin.CompareTo(horaFin) == 0 &
                                                            hp.Tipo.CompareTo("Personal") == 0
                                                      select hp);

                            int valor = Convert.ToInt32(value);

                            if (horarioPreferencia.Count() != 0)
                            {
                                var horarioPref = horarioPreferencia.First();
                                var diferenciaPref = valor - horarioPref.Preferencia;
                                horarioPref.Preferencia = valor;
                                repositorioHorarioPreferencia.Update(horarioPref);
                                var horarioPreferenciaDef = (from hp in listHorarioPref
                                                             where hp.Cedula == alumno.Cedula &
                                                                   hp.HoraInicio.CompareTo(horaIni) == 0 &
                                                                   hp.HoraFin.CompareTo(horaFin) == 0 &
                                                                   hp.Tipo.CompareTo("Definitivo") == 0
                                                             select hp).First();
                                horarioPreferenciaDef.Preferencia += diferenciaPref;
                                repositorioHorarioPreferencia.Update(horarioPreferenciaDef);
                            }
                            else
                            {
                                var horarioPref = new HorarioPreferencia
                                                        {
                                                            Cedula = alumno.Cedula,
                                                            HoraFin = horaFin,
                                                            HoraInicio = horaIni,
                                                            Preferencia = valor,
                                                            Tipo = "Personal"
                                                        };
                                repositorioHorarioPreferencia.Save(horarioPref);

                                /*OJO: Definir los parametros que influyan en este valor*/
                                int valorDefinitivo = valor;

                                horarioPref.Tipo = "Definitivo";
                                horarioPref.Preferencia = valorDefinitivo;
                                repositorioHorarioPreferencia.Save(horarioPref);
                            }
                        }
                        contador++;
                    }
                    FormsService.SignIn(alumno.Username, false /* createPersistentCookie */);
                }
                else
                {
                    ModelState.AddModelError("preferencias", "Todos las preferencias son requeridas.");
                    return View(alumno);
                }

                //Elimino todas las actividades inteligentes luego de hoy y resto las horas acumuladas
                var misActividadesIEliminar = repositorioActividad.GetAll().Where(a => a.Cedula == alumno.Cedula &&
                                                                               a.Tipo.CompareTo("Inteligente") == 0 &&
                                                                               a.HoraInicio >= DateTime.Now).ToList();
                foreach (var materia in misMaterias)
                {
                    double cantHoras = 0;
                    foreach (var actividad in misActividadesIEliminar)
                    {
                        if (actividad.IdMateria == materia)
                        {
                            cantHoras += (actividad.HoraFin.Hour + actividad.HoraFin.Minute / 60.00 + actividad.HoraFin.Second / 3600.00) -
                                         (actividad.HoraInicio.Hour + actividad.HoraInicio.Minute / 60.00 + actividad.HoraFin.Second / 3600.00);
                            repositorioActividad.Delete(actividad);
                        }
                    }
                    var mat = repositorioAlumnoMateria.GetAll().Where(aM => aM.IdMateria == materia &&
                                                                            aM.Cedula == alumno.Cedula).First();
                    mat.HorasAcumuladas -= cantHoras;
                    repositorioAlumnoMateria.Update(mat);
                }

                ActividadesInteligentes(alumno.Cedula);
            }
            else
            {
                ModelState.AddModelError("preferencias", "Todos las preferencias son requeridas.");
                return View(alumno);
            }
            return RedirectToAction("Index", "Home");
        }
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ValidateUser(model.UserName, model.Password))
                {
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    var roleEstudiante = Roles.GetUsersInRole("Estudiante");
                    bool flag = false;
                    foreach (var rol in roleEstudiante)
                    {
                        if (rol.CompareTo(model.UserName) == 0)
                        {
                            flag = true;
                        }
                    }
                    if (flag)
                    {
                        IRepositorio<Alumno> repoAlumno = new AlumnoRepositorio();
                        var miAlumno = repoAlumno.GetByUniqueAtribute(model.UserName);
                        if (miAlumno != null)
                        {
                            Session["cedula"] = miAlumno.Cedula;

                            /*
                             * Si no tengo actividades de clase
                             * invoco al trigger de Alumno
                             */
                            IRepositorio<Actividad> repositorioActividad = new ActividadRepositorio();
                            var misActividades = new List<Actividad>();

                            IRepositorio<ClaseEvaluacion> repositorioClaseE = new HorarioClaseRepositorio();
                            var listClaseEvaluacion = repositorioClaseE.GetAll().Where(cE => cE.Cedula == miAlumno.Cedula).ToList();

                            foreach (var claseEvaluacion in listClaseEvaluacion)
                            {
                                var actividad = repositorioActividad.GetById(claseEvaluacion.IdActividad);
                                if (actividad.Tipo.CompareTo("Clase") == 0 &&
                                    actividad.Periodo.CompareTo((_periodoActual)) == 0)
                                {
                                    misActividades.Add(actividad);
                                }
                            }
                            if (misActividades.Count == 0)
                            {
                                repoAlumno.Update(miAlumno);
                            }
                            /*
                             * Si no tengo actividades inteligentes
                             * en el periodo actual, se calculan
                             */
                            var actInteligentes =
                                repositorioActividad.GetAll().Where(a => a.Cedula == miAlumno.Cedula &&
                                                                         a.Tipo.CompareTo("Inteligente") == 0 &&
                                                                         a.Periodo.CompareTo(_periodoActual) == 0).ToList();
                            if (actInteligentes.Count() == 0)
                            {
                                IRepositorio<ClaseEvaluacion> repositorioHorarioClase = new HorarioClaseRepositorio();
                                var listCronograma = repositorioHorarioClase.GetAll().Where(alum => alum.Cedula == miAlumno.Cedula);

                                var listActividades = repositorioActividad.GetAll().Where(a => a.Periodo.CompareTo(_periodoActual) == 0);

                                var misMaterias = (from d in listCronograma
                                                   from c in listActividades
                                                   where c.Tipo.CompareTo("Clase") == 0 &&
                                                         d.IdActividad == c.IdActividad
                                                   select c.IdMateria).Distinct();

                                var misEvaluaciones = (from d in listCronograma
                                                       from c in listActividades
                                                       where c.Tipo.CompareTo("Evaluacion") == 0 &&
                                                             d.IdActividad == c.IdActividad
                                                       select c).ToList();

                                HorasPersonales(misMaterias, miAlumno);

                                IRepositorio<Materium> repositorioMateria = new MateriumRepositorio();
                                IRepositorio<AlumnoMaterium> repositorioAlumnoMat = new AlumnoMateriumRepositorio();
                                IRepositorio<PromedioFactor> repositorioPromedioFactor = new PromedioFactorRepositorio();
                                IList<PromedioFactor> listPromedioFactor = repositorioPromedioFactor.GetAll();

                                var mayorCredito = (from mat in repositorioMateria.GetAll()
                                                    select mat.Creditos).Max();

                                foreach (var miMateria in misMaterias)
                                {
                                    var alumnoMateria =
                                        repositorioAlumnoMat.GetAll().Where(aM => aM.IdMateria == miMateria &&
                                                                                  aM.Cedula == miAlumno.Cedula).First();
                                    if (alumnoMateria.Preferencia != 0.00)
                                    {
                                        var promedio = (from prom in listPromedioFactor
                                                        where prom.IdMateria == miMateria &&
                                                              prom.Factor.CompareTo("Promedio") == 0
                                                        select prom.Promedio).First();

                                        var porcentajeProm = (double)(((20 - promedio) * 100) / 20);

                                        var materia = repositorioMateria.GetById(miMateria);

                                        var uc = materia.Creditos;

                                        var porcentajeUC = (uc * 100) / mayorCredito;

                                        var porcentajePref = (alumnoMateria.Preferencia * 100) / 5.0;

                                        alumnoMateria.Prioridad = (porcentajePref + porcentajeProm + porcentajeUC) / 3;
                                    }
                                    else
                                    {
                                        var promedio = (from prom in listPromedioFactor
                                                        where prom.IdMateria == miMateria &&
                                                              prom.Factor.CompareTo("Promedio") == 0
                                                        select prom.Promedio).First();

                                        var porcentajeProm = (double)(((20 - promedio) * 100) / 20);

                                        var materia = repositorioMateria.GetById(miMateria);

                                        var uc = materia.Creditos;

                                        var porcentajeUC = (uc * 100) / mayorCredito;

                                        alumnoMateria.Prioridad = (porcentajeProm + porcentajeUC) / 2;
                                    }

                                    //Se toma en cuenta las notas obtenidas en las evaluaciones
                                    foreach (var miEvaluacion in misEvaluaciones)
                                    {
                                        var miNota = (from cE in listCronograma
                                                      where cE.IdActividad == miEvaluacion.IdActividad
                                                      select cE.Nota).First();
                                        if (miNota != 0.0)
                                        {
                                            const int x1 = 10;
                                            const int y1 = 0;
                                            const int x2 = 20;
                                            var y2 = -alumnoMateria.Prioridad * (miEvaluacion.Ponderacion / 100.00);
                                            var pendiente1 = (y2 - y1) / (x2 - x1);
                                            var factorM = (miNota * pendiente1) - y2;
                                            alumnoMateria.Prioridad += factorM;
                                        }
                                    }

                                    repositorioAlumnoMat.Update(alumnoMateria);
                                }
                                ActividadesInteligentes(miAlumno.Cedula);
                            }
                            if (!String.IsNullOrEmpty(returnUrl))
                            {
                                return Redirect(returnUrl);
                            }
                            return RedirectToAction("Index", "Home");
                        }
                    }
                    else
                    {
                        var roleProfesor = Roles.GetUsersInRole("Profesor");
                        flag = false;
                        foreach (var rol in roleProfesor)
                        {
                            if (rol.CompareTo(model.UserName) == 0)
                            {
                                flag = true;
                            }
                        }
                        if (flag)
                        {
                            IRepositorio<Profesor> repoProfesor = new ProfesorRepositorio();
                            var miProfesor = repoProfesor.GetByUniqueAtribute(model.UserName);
                            if (miProfesor != null)
                            {
                                Session["cedula"] = miProfesor.Cedula;
                                repoProfesor.Update(miProfesor);
                                if (!String.IsNullOrEmpty(returnUrl))
                                {
                                    return Redirect(returnUrl);
                                }
                                return RedirectToAction("IndexProfesor", "Home");
                            }
                        }
                    }
                }
                ModelState.AddModelError("NCIncorrecto", "El nombre de usuario o la contraseña especificados son incorrectos.");
            }
            // Si llegamos a este punto, es que se ha producido un error y volvemos a mostrar el formulario
            return View(model);
        }
        private void HorasPersonales(IEnumerable<int?> misMaterias, Alumno alumno)
        {
            var miEdad = (int)((_fechaActual - alumno.FechaNac).Days / 365.25);

            IRepositorio<DatosSociales> repositorioDatosSociales = new DatosSocialesRepositorio();
            var misDatosSociales =
                repositorioDatosSociales.GetByUniqueAtribute(alumno.Cedula.ToString());

            IRepositorio<PromedioFactor> repositorioPromedioFactor = new PromedioFactorRepositorio();
            var promedioFactor = repositorioPromedioFactor.GetAll();

            IRepositorio<Materium> repositorioMaterium = new MateriumRepositorio();
            // Se obtienen las horas base y se customiza segun los parametros del estudiante.
            foreach (int idMateria in misMaterias)
            {
                double horasBase = repositorioMaterium.GetById(idMateria).HorasBase;

                double promHistorico = 0;
                decimal nota = 0;
                int cantPersonalizacion = 0;

                // Personaliza segun la edad
                var fEdad = (from factor in promedioFactor
                             where factor.Factor.CompareTo("Edad") == 0 &&
                                   factor.Clasificacion.CompareTo(miEdad.ToString()) == 0 &&
                                   factor.IdMateria == idMateria
                             select factor);
                if (fEdad.Count() > 0)
                {
                    cantPersonalizacion++;
                    nota = fEdad.First().Promedio;
                    promHistorico = promHistorico + (double)nota;
                }

                //Personaliza segun Trabajo
                cantPersonalizacion++;
                if (misDatosSociales.Trabaja.CompareTo("Si") == 0)
                {
                    nota = (from factor in promedioFactor
                            where factor.Factor.CompareTo("Trabajo") == 0 &&
                                  factor.Clasificacion.CompareTo(misDatosSociales.RelacionTrabCarr) == 0 &&
                                  factor.IdMateria == idMateria
                            select factor.Promedio).First();
                }
                else
                {
                    nota = (from factor in promedioFactor
                            where factor.Factor.CompareTo("Trabajo") == 0 &&
                                  factor.Clasificacion.CompareTo("No Trabaja") == 0 &&
                                  factor.IdMateria == idMateria
                            select factor.Promedio).First();
                }
                promHistorico = promHistorico + Convert.ToDouble(nota);

                //Personaliza segun la materia
                cantPersonalizacion++;
                nota = (from factor in promedioFactor
                        where factor.Factor.CompareTo("Promedio") == 0 &&
                              factor.IdMateria == idMateria
                        select factor.Promedio).First();
                promHistorico = promHistorico + Convert.ToDouble(nota);

                //Personaliza segun el record de las materias que prelan esta materia
                IRepositorio<Requisito> repositorioRequisito = new RequisitoRepositorio();
                var misRequisitos = (from r in repositorioRequisito.GetAll()
                                     where r.IdMateriaHijo == idMateria
                                     select r.IdMateriaPadre).ToList();

                var prom = 0.0;
                if (misRequisitos.Count > 0)
                {
                    IRepositorio<SlRecordAcademico> repositorioSlRecord = new SlRecordAcademicoRepositorio();
                    IRepositorio<SlSeccion> repositorioSlSeccion = new SlSeccionRepositorio();
                    IRepositorio<SlMaterium> repositorioSlMateria = new SlMateriumRepositorio();
                    var anioPerdiodo = Convert.ToInt32(_periodoActual.Substring(0, 4));
                    var periodo = Convert.ToInt32(_periodoActual.Substring(4));
                    if (periodo > 21)
                    {
                        periodo--;
                    }
                    else
                    {
                        anioPerdiodo--;
                    }
                    var periodoAnterior = Convert.ToInt32(anioPerdiodo.ToString() + periodo.ToString());
                    var sum = 0;
                    foreach (var requisito in misRequisitos)
                    {
                        var materia = repositorioMaterium.GetById(requisito);
                        var slMateria = repositorioSlMateria.GetAll().Where(m => m.Nombre.CompareTo(materia.Nombre) == 0).First();
                        var slSeccion = repositorioSlSeccion.GetAll().Where(s => s.IdMateria == slMateria.IdMateria &&
                                                                                 s.Periodo.CompareTo(periodoAnterior) == 0).ToList();
                        var n = (from record in repositorioSlRecord.GetAll()
                                 from seccion in slSeccion
                                 where record.Cedula == alumno.Cedula &&
                                       record.IdSeccion == seccion.IdSeccion
                                 select record.Nota);
                        if (n.Count() > 0)
                        {
                            sum++;
                            prom += Convert.ToDouble(n.First());
                        }
                    }
                    if (prom > 0.0)
                    {
                        cantPersonalizacion++;
                        promHistorico += (prom / sum);
                    }
                }

                promHistorico = promHistorico / cantPersonalizacion;

                /*
                 * Segun el promedio obtenido segun las caracteristicas
                 * personales del alumno se le aumentan o disminuyen las
                 * horas de estudio segun una regla.
                 */
                const double pendiente = -0.075;
                var factorM = (promHistorico * pendiente) + 1.75;
                var horasPersonalizadas = horasBase * factorM;

                var misHorasPersonales = new AlumnoMaterium()
                {
                    IdMateria = idMateria,
                    Cedula = alumno.Cedula,
                    HorasPersonales = horasPersonalizadas
                };

                //Segun las notas obtenidas en las evaluaciones anteriores se afecta las horas personales
                IRepositorio<ClaseEvaluacion> repositorioHorarioClase = new HorarioClaseRepositorio();
                var listCronograma = repositorioHorarioClase.GetAll().Where(alum => alum.Cedula == alumno.Cedula).ToList();

                IRepositorio<Actividad> repositorioActividad = new ActividadRepositorio();
                var listActividades = repositorioActividad.GetAll().Where(a => a.Periodo.CompareTo(_periodoActual) == 0).ToList();

                var misEvaluaciones = (from d in listCronograma
                                       from c in listActividades
                                       where c.Tipo.CompareTo("Evaluacion") == 0 &&
                                             d.IdActividad == c.IdActividad
                                       select c).ToList();

                foreach (var miEvaluacion in misEvaluaciones)
                {
                    var miNota = (from cE in listCronograma
                                  where cE.IdActividad == miEvaluacion.IdActividad
                                  select cE.Nota).First();
                    if (miNota != 0.0)
                    {
                        const int x1 = 10;
                        const int y1 = 0;
                        const int x2 = 20;
                        var y2 = (misHorasPersonales.HorasPersonales * (miEvaluacion.Ponderacion / 100.00)) * -1;
                        var pendiente1 = (y2 - y1) / (x2 - x1);
                        var factorMat = (miNota * pendiente1) - y2;
                        misHorasPersonales.HorasPersonales += factorMat;
                    }
                }

                if (prom > 0.00)
                {
                    if (prom < 4)
                    {
                        misHorasPersonales.Preferencia = 5;
                    }
                    else if (prom < 8)
                    {
                        misHorasPersonales.Preferencia = 4;
                    }
                    else if (prom < 12)
                    {
                        misHorasPersonales.Preferencia = 3;
                    }
                    else if (prom < 16)
                    {
                        misHorasPersonales.Preferencia = 2;
                    }
                    else if (prom <= 20)
                    {
                        misHorasPersonales.Preferencia = 1;
                    }
                }
                IRepositorio<AlumnoMaterium> repositorioAlumnoMateria = new AlumnoMateriumRepositorio();
                repositorioAlumnoMateria.Update(misHorasPersonales);
            }
        }