/// <summary>
        /// Constructor para registrar una acción determinada en una tabla de un usuario
        /// </summary>
        /// <param name="acc"></param>
        /// <param name="usu"></param>
        /// <param name="tab"></param>
        /// <param name="id_tb"></param>
        /// <param name="n_id_tb"></param>
        public Historial(string acc, string usu,string tab,string id_tb,string n_id_tb,string ip)
        {
            Conexion db = new Conexion();         

            this.id = Guid.NewGuid().ToString();
            this.fecha = DateTime.Now;
            this.accion = acc;
            this.usuario = usu;
            this.tabla = tab;
            this.id_tabla = id_tb;
            this.n_id_tabla = n_id_tb;
            this.ip_conexion = ip;

            //Guardo en la BD
            db.Historial.Add(this);
            db.SaveChanges();
        }
        /// <summary>
        /// Constructor para registrar la entrada y salida del usuario
        /// </summary>
        /// <param name="acc"></param>
        /// <param name="usu"></param>
        public Historial(string acc,string usu,string evento,string ip)
        {
            Conexion db = new Conexion();           

            this.id = Guid.NewGuid().ToString();
            this.fecha = DateTime.Now;
            this.accion = acc;
            this.ip_conexion = ip;
            
            if(evento == "entrar"){
                Usuarios nuevo = db.Usuarios.First(m => m.login == usu);
                this.usuario = nuevo.id;
            }
            else
            {
                this.usuario = usu;
            }           

            //Guardo en la BD

            db.Historial.Add(this);
            db.SaveChanges();

        }
        public ActionResult EliminarFichero(string id) {

            string id_retorno = "";


            using(Conexion db = new Conexion()){

                Operaciones_Documentos eliminar = db.Operaciones_Documentos.SingleOrDefault(m => m.id == id);                
                db.Operaciones_Documentos.Remove(eliminar);
                db.SaveChanges();
                id_retorno = eliminar.operacion_id;

                string ruta = string.Format("{0}OperacionesF\\{1}\\{2}\\{3}", Server.MapPath(@"\"), eliminar.operacion_id, eliminar.tipo_fichero, eliminar.nombre_fichero);

                bool isExists = System.IO.Directory.Exists(ruta);

                if (!isExists)
                System.IO.File.Delete(ruta);


            }


            TempData["Mensaje"] = "Documento eliminado correctamente.";
            return RedirectToAction("Editar", "Operaciones", new {id= id_retorno});
        }
        public ActionResult Fichero_Otros(string id)
        {
            string fName = "";
            foreach (string fileName in Request.Files)
            {
                HttpPostedFileBase file = Request.Files[fileName];
                //Save file content goes here
                fName = file.FileName;
                if (file != null && file.ContentLength > 0)
                {

                    var originalDirectory = new DirectoryInfo(string.Format("{0}OperacionesF\\{1}", Server.MapPath(@"\"), id));

                    string pathString = System.IO.Path.Combine(originalDirectory.ToString(), "Otros");

                    bool isExists = System.IO.Directory.Exists(pathString);

                    if (!isExists)
                        System.IO.Directory.CreateDirectory(pathString);

                    var path = string.Format("{0}\\{1}", pathString, file.FileName.ToString().Replace(' ', '_'));
                    file.SaveAs(path);

                    using (Conexion db = new Conexion())
                    {

                        Operaciones_Documentos nuevo = new Operaciones_Documentos();
                        nuevo.nombre_fichero = file.FileName.ToString().Replace(' ', '_');
                        nuevo.operacion_id = id;
                        nuevo.tipo_fichero = "Otros";

                        db.Operaciones_Documentos.Add(nuevo);
                        db.SaveChanges();
                    } 

                }

            }


            return RedirectToAction("Editar", "Operaciones", new { id = id });
        }
         /// <summary>
         /// Método para actializar los medios de la Operación
         /// </summary>
         /// <param name="op_nuevo"></param>
         /// <param name="id"></param>
         /// <param name="ip"></param>
         /// <returns></returns>
         public async Task Actualizar(Operaciones_Medios_Propios op_nuevo, string id, string ip)
         {
             using(var db = new Conexion()){

                 decimal coste_total = 0;

                 //Eliminar las Subcontratas de esta Operación
                 List<Operaciones_Subcontratas> op_sub = db.Operaciones_Subcontratas.Where(m => m.operacion_id == op_nuevo.id).ToList();
                 db.Operaciones_Subcontratas.RemoveRange(op_sub);
                 await db.SaveChangesAsync();

                 List<Operaciones_TipoPersonal> intro_opp = new List<Operaciones_TipoPersonal>();
                 intro_opp = db.Operaciones_TipoPersonal.Where(m=>m.operacion == op_nuevo.id).ToList();
                 db.Operaciones_TipoPersonal.RemoveRange(intro_opp);
                 db.SaveChanges();
                 intro_opp.Clear();

                 int posicion = 0;

                 foreach (int i in op_nuevo.c_personal)
                 {
                     if (i != 0)
                     {
                         Operaciones_TipoPersonal n_opp = new Operaciones_TipoPersonal();
                         n_opp.operacion = op_nuevo.id;
                         n_opp.tipo_personal = op_nuevo.lista_personal[posicion];
                         n_opp.cantidad = i;
                         intro_opp.Add(n_opp);

                         //Sumar el coste total de la operación
                        var t_p = db.Tipo_Personal.SingleOrDefault(m => m.id == n_opp.tipo_personal);
                         coste_total = coste_total + (t_p.coste * i) * op_nuevo.tiempo_ejecucion;

                     }
                     posicion++;
                 };

                 
                 db.Operaciones_TipoPersonal.AddRange(intro_opp);
                 await db.SaveChangesAsync();

                 Historial nuevo = new Historial("Modificó Tipos de Personal", id, "usuario", ip);

                 List<Operaciones_TipoMaterial> intro_opm = new List<Operaciones_TipoMaterial>();
                 intro_opm = db.Operaciones_TipoMaterial.Where(m => m.operacion == op_nuevo.id).ToList();
                 db.Operaciones_TipoMaterial.RemoveRange(intro_opm);
                 await db.SaveChangesAsync();
                 intro_opm.Clear();

                 posicion = 0;

                 foreach (int i in op_nuevo.c_material)
                 {

                     if (i != 0)
                     {

                         Operaciones_TipoMaterial n_opp = new Operaciones_TipoMaterial();
                         n_opp.operacion = op_nuevo.id;
                         n_opp.tipo_material = op_nuevo.lista_material[posicion];
                         n_opp.cantidad = i;
                         intro_opm.Add(n_opp);

                         //Sumar el coste total de la operación
                         var t_p = db.Tipo_Material.SingleOrDefault(m => m.id == n_opp.tipo_material);
                         coste_total = coste_total + t_p.coste * i;

                     }
                     posicion++;
                 };

                 db.Operaciones_TipoMaterial.AddRange(intro_opm);
                 await db.SaveChangesAsync();

                 Historial nuevo_material = new Historial("Modificó Tipos de Material", id, "usuario", ip);


                 List<Operaciones_TipoMaquinaria> intro_opma = new List<Operaciones_TipoMaquinaria>();
                 intro_opma = db.Operaciones_TipoMaquinaria.Where(m => m.operacion == op_nuevo.id).ToList();
                 db.Operaciones_TipoMaquinaria.RemoveRange(intro_opma);
                 await db.SaveChangesAsync();
                 intro_opma.Clear();

                 posicion = 0;

                 foreach (int i in op_nuevo.c_maquinaria)
                 {

                     if (i != 0)
                     {
                         Operaciones_TipoMaquinaria n_opp = new Operaciones_TipoMaquinaria();
                         n_opp.operacion = op_nuevo.id;
                         n_opp.tipo_maquinaria = op_nuevo.lista_maquinaria[posicion];
                         n_opp.cantidad = i;
                         intro_opma.Add(n_opp);

                         //Sumar el coste total de la operación
                         var t_p = db.Tipo_Maquinaria.SingleOrDefault(m => m.id == n_opp.tipo_maquinaria);
                         coste_total = coste_total + (t_p.coste * i)*op_nuevo.tiempo_ejecucion;
                     }
                     posicion++;
                 };

                 db.Operaciones_TipoMaquinaria.AddRange(intro_opma);
                 await db.SaveChangesAsync();
                 Historial nuevo_maquinarias = new Historial("Modificó Tipos de Maquinarias", id, "usuario", ip);


                 Operaciones operaciones = await db.Operaciones.FindAsync(op_nuevo.id);

                 operaciones.coste_total = coste_total;
                 operaciones.medios = "propios";

                 db.Entry(operaciones).State = EntityState.Modified;
                 await db.SaveChangesAsync();

             }     
         }
        public async Task<ActionResult> Editar(EditarUsuario model)
        {
            if (ModelState.IsValid)
            {

                var user = await UserManager.FindByIdAsync(model.id);
           
                user.nombre = model.nombre;
                user.apellido1 = model.apellido1;
                user.apellido2 = model.apellido2;
                user.telefono = model.telefono;
                user.email = model.email;
                user.UserName = model.UserName;               

                var result = await UserManager.UpdateAsync(user);

                if (result.Succeeded)
                {                  
                    ApplicationDbContext dba = new ApplicationDbContext();
                    Conexion db = new Conexion();
                    List<IdentityUserRole> lista_roles_usu = dba.User_Role.Where(m => m.UserId == user.Id).ToList();
                    dba.User_Role.RemoveRange(lista_roles_usu);
                    dba.SaveChanges();

                    List<UsuariosGrupo> grupoUR = db.UsuariosGrupo.Where(m => m.idusuario == user.Id).ToList();
                    db.UsuariosGrupo.RemoveRange(grupoUR);
                    db.SaveChanges();
                    grupoUR.Clear();


                    try {
                    foreach (var role in model.rol)
                    {
                        UsuariosGrupo inGrupo = new UsuariosGrupo();
                        inGrupo.idgrupousuario = role;
                        inGrupo.idusuario = user.Id;

                        grupoUR.Add(inGrupo);

                        List<GrupoU_Roles> listaRoles = db.GrupoU_Roles.Where(m=>m.idgrupo== role).ToList();

                            foreach (var intro in listaRoles)
                            {
                                var roless = db.Roles.FirstOrDefault(m=>m.Id == intro.idrol);
                            var isInRole = await UserManager.IsInRoleAsync(user.Id, roless.Name);
                                if (!isInRole)
                                {
                                    await UserManager.AddToRoleAsync(user.Id, roless.Name);
                                }
                            }
                        }

                    db.UsuariosGrupo.AddRange(grupoUR);
                    db.SaveChanges();
                    }
                    catch (Exception e)
                    {
                    }

                    Historial nuevo = new Historial("Modificó", User.Identity.GetUserId(), "usuario", user.Id, user.UserName, Request.UserHostAddress);               
                    TempData["Mensaje"] = "Datos del Usuario modificados correctamente.";
                    
                    //Para Crearlo y automaticamente longuearlo
                    //await SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Editar", "Acceso", new {id= user.Id });
                }
                else
                {
                    AddErrors(result);
                }
            }
           
            //Si llegamos a este punto, es que se ha producido un error y volvemos a mostrar el formulario.            

            return View(model);
        }
        public async Task<ActionResult> Nuevo(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {

                StringHash cod_secreto = new StringHash();
                TextoAleatorio text = new TextoAleatorio();

                var user = new ApplicationUser() { UserName = model.UserName,
                                                   nombre = model.nombre,
                                                   apellido1= model.apellido1,
                                                   apellido2 = model.apellido2,
                                                   telefono = model.telefono,
                                                   email= model.email,
                                                   fecha_creado = DateTime.Now,
                                                   cod_secreto = cod_secreto.Encrypt(text.Texto(), true, model.UserName)                                           
                };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    //Crea Rol por defecto
                    var rol = await UserManager.AddToRoleAsync(user.Id,"Lector");

                    UsuariosGrupo inGrupo = new UsuariosGrupo();
                    inGrupo.idgrupousuario = "8127f8b1-ff6e-4b21-bdd1-c3c9d1f9e440";
                    inGrupo.idusuario = user.Id;

                    Conexion db = new Conexion();
                    db.UsuariosGrupo.Add(inGrupo);
                    db.SaveChanges();

                    Historial nuevo = new Historial("Creó", User.Identity.GetUserId(), "usuario", user.Id, user.UserName, Request.UserHostAddress);

                    //Para Crearlo y automaticamente longuearlo
                    //await SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Editar", "Acceso", new {id=user.Id });
                }
                else
                {
                    AddErrors(result);
                }
            }

            // Si llegamos a este punto, es que se ha producido un error y volvemos a mostrar el formulario
            return View(model);
        }
        public async Task<ActionResult> Index(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var user = await UserManager.FindAsync(model.UserName, model.Password);
                if (user != null)
                {
                    await SignInAsync(user, model.RememberMe);

                    Conexion db = new Conexion();
                    Usuarios usuario = db.Usuarios.First(m=>m.login == user.UserName);
                    usuario.fecha_ul_acceso = DateTime.Now;
                    db.SaveChanges();

                    var cadena = HttpContext;
                  
                    Historial nuevo = new Historial("Auntenticó", model.UserName, "entrar", Request.UserHostAddress);

                    return RedirectToLocal(returnUrl);
                }
                else
                {
                    ModelState.AddModelError("", "Usuario o Contraseña no es correcto.");
                }
            }

            // Si llegamos a este punto, es que se ha producido un error y volvemos a mostrar el formulario
            return View(model);
        }