public ActionResult Editar(MovimientoTemp movimientoTemp, List<Item_MovPieza> ListaPiezas, string Motivo, bool ForzarMovimiento = false)
        {
            db = new RecordFCSContext();

            #region Validaciones previas

            if (movimientoTemp.EstadoMovimiento == EstadoMovimientoTemp.Concluido_SinValidar && movimientoTemp.EsValido)
                movimientoTemp.EstadoMovimiento = EstadoMovimientoTemp.Concluido;

            ////cambiar el estado del movimiento dependiendo la fecha y hora
            //if (movimientoTemp.EstadoMovimiento != EstadoMovimientoTemp.Cancelado)
            //{
            //    if (movimientoTemp.FechaSalida < DateTime.Now)
            //    {
            //        movimientoTemp.EstadoMovimiento = EstadoMovimientoTemp.Concluido;
            //    }
            //    else
            //    {
            //        movimientoTemp.EstadoMovimiento = EstadoMovimientoTemp.Procesando;
            //    }
            //}

            //Separar en listas las piezas

            //lista de piezas existentes en el movimiento
            var listaGuidActual = db.MovimientoTempPiezas.Where(a => a.MovimientoTempID == movimientoTemp.MovimientoTempID).Select(a => a.PiezaID).ToList();
            //lista de piezas que se agregaran al movimiento
            var listaAdd = new List<MovimientoTempPieza>();
            //lista de piezas que se editaran
            var listaEdit = new List<MovimientoTempPieza>();

            ListaPiezas = ListaPiezas == null ? new List<Item_MovPieza>() : ListaPiezas;

            foreach (var item in ListaPiezas)
            {
                var existeEnMov = listaGuidActual.Where(a => a == item.PiezaID).Count() > 0 ? true : false;

                var temp = new MovimientoTempPieza()
                {
                    Comentario = item.Comentario,
                    EnError = item.EnError,
                    EsPendiente = item.EsPendiente,
                    MovimientoTempID = movimientoTemp.MovimientoTempID,
                    PiezaID = item.PiezaID,
                    SeMovio = item.SeMovio,
                    FolioPieza = item.FolioPieza
                };

                temp.Comentario = item.EnError ? item.Comentario : "";

                if (!existeEnMov)
                {
                    // C R E A R
                    temp.EsPendiente = true;
                    temp.SeMovio = false;
                    listaAdd.Add(temp);
                }
                else
                {
                    // E D I T A R
                    listaEdit.Add(temp);

                    //quitarlo de la lista existente
                    listaGuidActual.Remove(item.PiezaID);
                }
            }

            #endregion

            //las piezas que no estuvieron eliminarlas
            //y buscar el movimiento anterior donde fueron validas
            //para regresar el estatus.
            if (ModelState.IsValid)
            {
                var fechaEdicion = DateTime.Now;

                movimientoTemp.FechaUltimaEjecucion = fechaEdicion;

                #region Crear el historial del movimiento

                //------ Logica HISTORIAL

                #region Generar el historial

                //objeto del formulario
                var objeto = movimientoTemp;
                //Objeto de la base de datos
                var objetoDB = db.MovimientosTemp.Find(movimientoTemp.MovimientoTempID);
                //tabla o clase a la que pertenece
                var tablaNombre = objeto.GetType().Name;
                //llave primaria del objeto
                var llavePrimaria = objetoDB.MovimientoTempID.ToString();

                //generar el historial
                var historialLog = HistorialLogica.EditarEntidad(
                    objeto,
                    objetoDB,
                    tablaNombre,
                    llavePrimaria,
                    User.UsuarioID,
                    db,
                    Motivo,
                    fechaEdicion
                    );

                #endregion

                #region Guardar el historial

                if (historialLog != null)
                {
                    //Cambiar el estado a la entidad a modificada
                    db.Entry(objetoDB).State = EntityState.Modified;
                    //Guardamos la entidad modificada
                    db.SaveChanges();

                    //Guardar el historial
                    db.HistorialLogs.Add(historialLog);
                    db.SaveChanges();
                }

                #endregion

                //------

                #endregion

                AlertaSuccess("Se edito el movimiento: <b>" + movimientoTemp.Folio + "</b>", true);

                //Crear el historial de las piezas del movimiento
                //Agregar, Editar y Eliminar las piezas
                //No se cambiara el estatus a las piezas ya que esto se hara automaticamente o mediante permisos especiales

                //Agregar
                #region Lista Agregar

                db = new RecordFCSContext();
                db.Configuration.LazyLoadingEnabled = false;

                foreach (var item in listaAdd)
                {

                    var ordenActual = db.MovimientoTempPiezas.Where(a => a.PiezaID == item.PiezaID).Count() > 0 ? db.MovimientoTempPiezas.Where(a => a.PiezaID == item.PiezaID).OrderByDescending(a => a.Orden).FirstOrDefault().Orden : 0;

                    item.Orden = item.EnError ? 0 : ordenActual + 1;

                    var temp = ListaPiezas.FirstOrDefault(a => a.PiezaID == item.PiezaID);

                    db.MovimientoTempPiezas.Add(item);

                    //------ Logica HISTORIAL

                    #region Generar el historial

                    //generar el historial
                    var historialLogAdd = HistorialLogica.CrearEntidad(
                        item,
                        "MovimientoTempPieza",
                        item.MovimientoTempID + "," + item.PiezaID,
                        User.UsuarioID,
                        db,
                        fechaEdicion
                        );

                    #endregion

                    #region Agrega el historial

                    if (historialLogAdd != null)
                    {
                        //Guardar el historial
                        db.HistorialLogs.Add(historialLogAdd);
                        AlertaSuccess("Se agrego la pieza [<b>" + temp.FolioPieza + "</b>]", true);
                    }
                    else
                    {
                        AlertaSuccess("No se pudo agregar la pieza [<b>" + temp.FolioPieza + "</b>]", true);
                    }
                    #endregion

                    //------

                }

                #region Guardar el historial y la entidad

                //Guardar todo
                db.SaveChanges();

                #endregion

                #endregion

                //Editar
                #region Lista Editar

                db = new RecordFCSContext();
                db.Configuration.LazyLoadingEnabled = false;

                foreach (var item in listaEdit.ToList())
                {

                    //Piezas SeMovio = no se pueden edita

                    //buscar la pieza
                    //var pieza = db.Piezas.Find(item.PiezaID);
                    var piezaMovOriginal = db.MovimientoTempPiezas.FirstOrDefault(a => a.PiezaID == item.PiezaID && a.MovimientoTempID == movimientoTemp.MovimientoTempID);

                    if (piezaMovOriginal.SeMovio)
                    {
                        listaEdit.Remove(item);
                    }
                    else
                    {
                        //saber si la pieza cambio en el campo error
                        //valor original - valor nuevo
                        bool ConCambios = piezaMovOriginal.EnError != item.EnError;

                        if (ConCambios)
                        {
                            //Sufrio cambios
                            if (item.EnError)
                            {
                                //ahora con errores
                                //item.Orden = 0;
                                item.EnError = true;
                                item.EsPendiente = true;
                                item.SeMovio = false;
                            }
                            else
                            {
                                //ahora sin errores
                                if (piezaMovOriginal.Orden == 0)
                                {
                                    //generar un orden
                                    var ordenActual = db.MovimientoTempPiezas.Where(a => a.PiezaID == item.PiezaID).Count() > 0 ? db.MovimientoTempPiezas.Where(a => a.PiezaID == item.PiezaID).OrderByDescending(a => a.Orden).FirstOrDefault().Orden : 0;
                                    item.Orden = item.EnError ? 0 : ordenActual + 1;
                                }

                                item.Comentario = "";
                                item.EnError = false;
                                item.EsPendiente = true;
                                item.SeMovio = false;
                            }
                        }
                        else
                        {
                            item.Comentario = piezaMovOriginal.Comentario;
                            item.EnError = piezaMovOriginal.EnError;
                            item.EsPendiente = piezaMovOriginal.EsPendiente;
                            item.Orden = piezaMovOriginal.Orden;
                            item.SeMovio = piezaMovOriginal.SeMovio;
                        }

                        piezaMovOriginal = null;

                        //buscar el objeto
                        var itemTemp = db.MovimientoTempPiezas.Find(item.MovimientoTempID, item.PiezaID);
                        itemTemp.Comentario = item.Comentario;
                        itemTemp.EnError = item.EnError;
                        itemTemp.EsPendiente = item.EsPendiente;
                        itemTemp.Orden = item.Orden;
                        itemTemp.SeMovio = item.SeMovio;
                        itemTemp.FolioPieza = item.FolioPieza;

                        //------ Logica HISTORIAL

                        #region Generar el historial

                        //objeto del formulario
                        var objetoEdit = itemTemp;
                        //Objeto de la base de datos
                        var objetoDBEdit = db.MovimientoTempPiezas.Find(itemTemp.MovimientoTempID, itemTemp.PiezaID);
                        //tabla o clase a la que pertenece
                        var tablaNombreEdit = "MovimientoTempPieza";
                        //llave primaria del objeto
                        var llavePrimariaEdit = objetoDBEdit.MovimientoTempID + "," + objetoDBEdit.PiezaID;

                        //generar el historial
                        var historialLogEdit = HistorialLogica.EditarEntidad(
                            objetoEdit,
                            objetoDBEdit,
                            tablaNombreEdit,
                            llavePrimariaEdit,
                            User.UsuarioID,
                            db,
                            Motivo,
                            fechaEdicion
                            );

                        #endregion

                        #region Agrega el historial

                        if (historialLogEdit != null)
                        {
                            //Cambiar el estado a la entidad a modificada
                            db.Entry(objetoDBEdit).State = EntityState.Modified;

                            //Guardar el historial
                            db.HistorialLogs.Add(historialLogEdit);
                        }

                        #endregion

                        //------

                    }
                }

                #region Guardar el historial y la entidad

                //Guardar todo
                db.SaveChanges();

                #endregion

                #endregion

                //Eliminar
                #region ListaEliminar

                db = new RecordFCSContext();
                //db.Configuration.LazyLoadingEnabled = false;

                foreach (var PiezaIDDel in listaGuidActual)
                {

                    var item = db.MovimientoTempPiezas.FirstOrDefault(a => a.PiezaID == PiezaIDDel && a.MovimientoTempID == movimientoTemp.MovimientoTempID);

                    bool esEliminable = false;
                    string Folio = "";
                    bool RegresarHistorial = false;

                    //saber si es eliminable y si se puede regresar el estado
                    if (item != null)
                    {
                        bool esUltimo = db.MovimientoTempPiezas.Where(a => a.PiezaID == item.PiezaID && a.Orden > item.Orden && !a.EnError).Count() > 0 ? false : true;
                        bool conPendientes = db.MovimientoTempPiezas.Where(a => a.PiezaID == item.PiezaID && a.EsPendiente && a.MovimientoTempID != movimientoTemp.MovimientoTempID && !a.EnError).Count() > 0 ? true : false;

                        Folio = item.Pieza.ImprimirFolio();

                        if (item.SeMovio)
                        {
                            if (esUltimo)
                            {
                                esEliminable = true;
                                RegresarHistorial = true;
                            }
                        }
                        else
                        {
                            if (item.EsPendiente)
                            {
                                esEliminable = true;
                            }
                        }
                    }

                    //es eliminable
                    if (esEliminable)
                    {
                        db.MovimientoTempPiezas.Remove(item);

                        //------ Logica HISTORIAL

                        #region Generar el historial

                        // Generar el historial
                        var historialLogDel =
                            HistorialLogica.EliminarEntidad(
                            item,
                            "MovimientoTempPieza",
                            item.MovimientoTempID + "," + item.PiezaID,
                            User.UsuarioID,
                            db,
                            fechaEdicion);

                        #endregion

                        #region Guardar el historial

                        //Guardar cambios si todo salio correcto
                        if (historialLogDel != null)
                        {
                            //Guardar el historial
                            db.HistorialLogs.Add(historialLogDel);

                            AlertaDanger("Se elimino la pieza [<b>" + Folio + "</b>]", true);

                        }

                        #endregion

                        //------

                        //Regresar el estado de la pieza
                        if (RegresarHistorial)
                        {
                            item = null;
                            var pieza = db.Piezas.Find(PiezaIDDel);
                            if (pieza != null)
                            {
                                if (pieza.UbicacionID == movimientoTemp.UbicacionDestinoID)
                                {
                                    pieza.UbicacionID = movimientoTemp.UbicacionOrigenID;

                                    //------ Logica HISTORIAL

                                    #region Generar el historial

                                    //objeto del formulario
                                    var objetoDelUbi = pieza;
                                    //Objeto de la base de datos
                                    var objetoDBDelUbi = db.Piezas.Find(pieza.PiezaID);
                                    //tabla o clase a la que pertenece
                                    var tablaNombreDelUbi = "Pieza";
                                    //llave primaria del objeto
                                    var llavePrimariaDelUbi = objetoDBDelUbi.PiezaID.ToString();

                                    //generar el historial
                                    var historialLogDelUbi = HistorialLogica.EditarEntidad(
                                        objetoDelUbi,
                                        objetoDBDelUbi,
                                        tablaNombreDelUbi,
                                        llavePrimariaDelUbi,
                                        User.UsuarioID,
                                        db,
                                        "Retornar Movimiento: " + movimientoTemp.Folio,
                                        fechaEdicion
                                        );

                                    #endregion

                                    #region Guardar el historial

                                    if (historialLogDelUbi != null)
                                    {
                                        //Cambiar el estado a la entidad a modificada
                                        db.Entry(objetoDBDelUbi).State = EntityState.Modified;

                                        //Guardar el historial
                                        db.HistorialLogs.Add(historialLogDelUbi);

                                    }

                                    #endregion

                                    //------

                                }
                            }
                        }
                    }
                }

                #region Guardar el historial

                //Guardar todo
                db.SaveChanges();

                #endregion

                #endregion

                if (ForzarMovimiento)
                {
                    //Logica para forzar el movimiento
                    db = new RecordFCSContext();

                    var mov = db.MovimientosTemp.Find(movimientoTemp.MovimientoTempID);

                    var EstadoActual = mov.EstadoMovimiento.Value;

                    //Solo acepta movimientos que no esten cancelados o que tengan retorno
                    if (mov.MovimientoTempPiezas.Where(a => !a.SeMovio && !a.EnError && a.EsPendiente).Count() > 0)
                    {
                        if (EstadoActual == EstadoMovimientoTemp.Concluido ||
                            EstadoActual == EstadoMovimientoTemp.Concluido_SinValidar ||
                            EstadoActual == EstadoMovimientoTemp.Procesando)
                        {
                            //Sirve para cambiar la ubicacion a las piezas

                            //Elegir el estado al cual pasara
                            //Ignorando la fecha
                            switch (EstadoActual)
                            {
                                case EstadoMovimientoTemp.Concluido_SinValidar:
                                    //Comprobar si el movimiento ya es valido
                                    if (mov.EsValido)
                                        EstadoActual = EstadoMovimientoTemp.Concluido;
                                    break;
                                case EstadoMovimientoTemp.Procesando:
                                    //Comprobar si el movimiento ya es valido
                                    if (mov.EsValido)
                                        EstadoActual = EstadoMovimientoTemp.Concluido;
                                    else
                                        EstadoActual = EstadoMovimientoTemp.Concluido_SinValidar;
                                    break;
                            }

                            mov.EstadoMovimiento = EstadoActual;

                            EjecutarMovimiento(mov, EstadoActual, fechaEdicion);

                        }

                    }

                }

                return Json(new { success = true, url = Url.Action("Detalles", new { id = movimientoTemp.MovimientoTempID }) });
            }

            //Si Error
            #region Logica si ocurre un error

            var listaUbicaciones = db.Ubicaciones.Where(a => a.Status).Select(a => new { a.Nombre, a.UbicacionID }).OrderBy(a => a.Nombre);

            //Ubicacion destino no puede editarse si se encuentra por lo menos una Pieza Procesada
            ViewBag.UbiDestinoEnabled = movimientoTemp.MovimientoTempPiezas.Where(a => a.SeMovio).Count() == 0 ? true : false;

            ViewBag.UbicacionDestinoID = new SelectList(listaUbicaciones, "UbicacionID", "Nombre", movimientoTemp.UbicacionDestinoID);

            #region Validar navegacion de movimientos

            // 1 2 3 4 [5] 6 7 8 9 10
            // [1] 2 3 4 5 6 7 8 9 10
            // 1 2 3 4 5 6 7 8 9 9 [10]

            MovimientoTemp movTemp = null;
            movTemp = db.MovimientosTemp.Where(a => a.Folio < movimientoTemp.Folio).OrderByDescending(a => a.Folio).FirstOrDefault();
            ViewBag.MovAnterior = movTemp == null ? Guid.Empty : movTemp.MovimientoTempID;

            movTemp = db.MovimientosTemp.Where(a => a.Folio > movimientoTemp.Folio).OrderBy(a => a.Folio).FirstOrDefault();
            ViewBag.MovSiguiente = movTemp == null ? Guid.Empty : movTemp.MovimientoTempID;

            #endregion

            #endregion

            return View(movimientoTemp);
        }
        private bool EjecutarMovimiento(MovimientoTemp mov, EstadoMovimientoTemp Estado, DateTime Fecha, string Motivo = null)
        {
            bool bandera = false;

            try
            {
                db = new RecordFCSContext();

                Motivo = Motivo ?? "Ejecución del movimiento.";
                //Revalidar las piezas del movimiento que fueron validas y que no se hayan movido y sean pendientes
                int contadorPMovidas = 0;

                foreach (var PiezaID in mov.MovimientoTempPiezas.Where(a => !a.EnError && !a.SeMovio && a.EsPendiente).Select(a => a.PiezaID).ToList())
                {

                    #region Buscar la pieza con su movimiento

                    //Buscar la pieza y la pieza en el movimiento
                    var pieza = db.Piezas.Find(PiezaID);
                    var piezaEnMovReal = pieza.MovimientoTempPiezas.FirstOrDefault(a => a.MovimientoTempID == mov.MovimientoTempID);

                    #endregion

                    #region Declaracion y asignaciones

                    piezaEnMovReal.EnError = false;
                    piezaEnMovReal.EsPendiente = true;
                    piezaEnMovReal.SeMovio = false;

                    string comentario = "";

                    #endregion

                    #region Validacion 1: Asignada en movimientos

                    #region Buscar donde sea Pendiente y sin errores

                    //lista de movimientos ID
                    //Buscar la pieza en todos los movimientos excepto este, donde sea pendiente y no tenga errrores.

                    List<int> listaMov_ID =
                        db.MovimientoTempPiezas
                        .Where(a =>
                            a.PiezaID == PiezaID &&
                            a.MovimientoTempID != mov.MovimientoTempID &&
                            a.EsPendiente && !a.EnError
                            )
                            .Select(a => a.MovimientoTemp.Folio).ToList();

                    #endregion

                    #region Buscar en Concluido sin validar

                    listaMov_ID.AddRange(
                        db.MovimientoTempPiezas.Where(a => a.PiezaID == PiezaID && a.MovimientoTempID != mov.MovimientoTempID &&
                        a.MovimientoTemp.EstadoMovimiento == EstadoMovimientoTemp.Concluido_SinValidar &&
                        a.SeMovio).Select(a => a.MovimientoTemp.Folio).ToList()
                        );

                    #endregion

                    #region Buscar en Cancelado

                    listaMov_ID.AddRange(
                        db.MovimientoTempPiezas.Where(a => a.PiezaID == PiezaID && a.MovimientoTempID != mov.MovimientoTempID &&
                        a.MovimientoTemp.EstadoMovimiento == EstadoMovimientoTemp.Cancelado &&
                        a.SeMovio).Select(a => a.MovimientoTemp.Folio).ToList()
                        );

                    #endregion

                    #region Buscar en Retornado

                    listaMov_ID.AddRange(
                        db.MovimientoTempPiezas.Where(a => a.PiezaID == PiezaID && a.MovimientoTempID != mov.MovimientoTempID &&
                        a.MovimientoTemp.EstadoMovimiento == EstadoMovimientoTemp.Retornado &&
                        a.SeMovio).Select(a => a.MovimientoTemp.Folio).ToList()
                        );

                    #endregion

                    //Si existe con estas condiciones entonces no es disponible
                    foreach (var Folio in listaMov_ID)
                        comentario += " [" + Folio + "]";

                    //Comprobar que no haya estado en algun movimiento
                    if (!string.IsNullOrWhiteSpace(comentario))
                    {
                        piezaEnMovReal.Comentario = "Asignada en:" + comentario + ". ";
                        piezaEnMovReal.EnError = true;
                    }

                    #endregion

                    #region Validacion 2: Ubicacion

                    //validar que la ubicacion de la pieza sea la misma que este movimiento

                    //puede haber piezas que UbicacionID sea null y en este caso se concidera valida.
                    if (pieza.UbicacionID != null)
                    {
                        //Validar que la ubicacion Origen sea igual a la de la pieza
                        if (mov.UbicacionOrigenID != pieza.UbicacionID)
                        {
                            piezaEnMovReal.Comentario += "No comparte la misma ubicación origen. ";
                            piezaEnMovReal.EnError = true;
                        }
                    }

                    #endregion

                    #region Validacion 3: En ultimo movimiento

                    if (pieza.MovimientoTempPiezas.Where(a => a.Orden > piezaEnMovReal.Orden && !a.EnError).Count() > 0)
                    {
                        piezaEnMovReal.Comentario += "No esta en su último movimiento. ";
                        piezaEnMovReal.EnError = true;
                    }

                    #endregion

                    //Sin errores entoces proceder a realizar el cambio de ubicacion

                    #region Cambio de Ubicacion

                    if (!piezaEnMovReal.EnError)
                    {
                        //Sin errores

                        #region Asignar un orden al movimiento de la pieza

                        if (piezaEnMovReal.Orden == 0)
                        {
                            var ordenActual = pieza.MovimientoTempPiezas.Count > 0 ? pieza.MovimientoTempPiezas.OrderByDescending(a => a.Orden).FirstOrDefault().Orden : 0;
                            piezaEnMovReal.Orden = piezaEnMovReal.EnError ? 0 : ordenActual + 1;
                        }

                        #endregion

                        //Ejecutar el cambio de ubicacion
                        pieza.UbicacionID = mov.UbicacionDestinoID;

                        //------ Logica HISTORIAL

                        #region Generar el historial

                        //objeto del formulario
                        var objeto = pieza;
                        //Objeto de la base de datos
                        var objetoDB = db.Piezas.Find(pieza.PiezaID);
                        //tabla o clase a la que pertenece
                        var tablaNombre = "Pieza";
                        //llave primaria del objeto
                        var llavePrimaria = objetoDB.PiezaID.ToString();

                        //generar el historial
                        var historialLog = HistorialLogica.EditarEntidad(
                            objeto,
                            objetoDB,
                            tablaNombre,
                            llavePrimaria,
                            User.UsuarioID,
                            db,
                            Motivo + "[Forzado]",
                            Fecha
                            );

                        #endregion

                        #region Guardar el historial

                        if (historialLog != null)
                        {
                            //Cambiar el estado a la entidad a modificada
                            db.Entry(objetoDB).State = EntityState.Modified;
                            //Guardamos la entidad modificada
                            db.SaveChanges();

                            //Guardar el historial
                            db.HistorialLogs.Add(historialLog);
                            db.SaveChanges();

                            contadorPMovidas++;

                            piezaEnMovReal.SeMovio = true;
                            piezaEnMovReal.EsPendiente = false;
                            piezaEnMovReal.EnError = false;
                            piezaEnMovReal.Comentario = "";
                        }
                        else
                        {
                            throw new Exception();
                        }
                        #endregion

                        //------

                    }
                    else
                    {
                        //Con errores
                        piezaEnMovReal.Orden = 0;
                    }

                    pieza = null;

                    #endregion

                    #region Asignacion de nuevos valores

                    //buscar el objeto
                    var itemTemp = db.MovimientoTempPiezas.Find(mov.MovimientoTempID, PiezaID);
                    itemTemp.Comentario = piezaEnMovReal.Comentario;
                    itemTemp.EnError = piezaEnMovReal.EnError;
                    itemTemp.EsPendiente = piezaEnMovReal.EsPendiente;
                    itemTemp.Orden = piezaEnMovReal.Orden;
                    itemTemp.SeMovio = piezaEnMovReal.SeMovio;

                    piezaEnMovReal = null;

                    #endregion

                    //------ Logica HISTORIAL

                    #region Generar el historial

                    //objeto del formulario
                    var objeto2 = itemTemp;
                    //Objeto de la base de datos
                    var objetoDB2 = db.MovimientoTempPiezas.Find(mov.MovimientoTempID, PiezaID);
                    //tabla o clase a la que pertenece
                    var tablaNombre2 = "MovimientoTempPieza";
                    //llave primaria del objeto
                    var llavePrimaria2 = objetoDB2.MovimientoTempID + "," + objetoDB2.PiezaID;

                    //generar el historial
                    var historialLog2 = HistorialLogica.EditarEntidad(
                        objeto2,
                        objetoDB2,
                        tablaNombre2,
                        llavePrimaria2,
                        User.UsuarioID,
                        db,
                        Motivo + "[Forzado]",
                        Fecha
                        );

                    #endregion

                    #region Guardar el historial

                    if (historialLog2 != null)
                    {
                        //Cambiar el estado a la entidad a modificada
                        db.Entry(objetoDB2).State = EntityState.Modified;
                        //Guardamos la entidad modificada
                        db.SaveChanges();

                        //Guardar el historial
                        db.HistorialLogs.Add(historialLog2);
                        db.SaveChanges();

                    }
                    else
                    {
                        throw new Exception();
                    }
                    #endregion

                    //------

                }

                //Cambio del estatus
                //Solo si se actualizo la ubicacion de por lo menos 1 pieza

                if (contadorPMovidas > 0)
                {
                    //saber cual sera el estatus Concluido ó Concluido_SinValidar
                    if (mov.EsValido)
                        mov.EstadoMovimiento = EstadoMovimientoTemp.Concluido;
                    else
                        mov.EstadoMovimiento = EstadoMovimientoTemp.Concluido_SinValidar;
                }

                //------ Logica HISTORIAL

                #region Generar el historial

                //objeto del formulario
                var objeto3 = mov;
                //Objeto de la base de datos
                var objetoDB3 = db.MovimientosTemp.Find(mov.MovimientoTempID);
                //tabla o clase a la que pertenece
                var tablaNombre3 = "MovimientoTemp";
                //llave primaria del objeto
                var llavePrimaria3 = objetoDB3.MovimientoTempID.ToString();

                //generar el historial
                var historialLog3 = HistorialLogica.EditarEntidad(
                    objeto3,
                    objetoDB3,
                    tablaNombre3,
                    llavePrimaria3,
                    User.UsuarioID,
                    db,
                    Motivo + "[Forzado]",
                    Fecha
                    );

                #endregion

                #region Guardar el historial

                if (historialLog3 != null)
                {
                    //Cambiar el estado a la entidad a modificada
                    db.Entry(objetoDB3).State = EntityState.Modified;
                    //Guardamos la entidad modificada
                    db.SaveChanges();

                    //Guardar el historial
                    db.HistorialLogs.Add(historialLog3);
                    db.SaveChanges();
                }
                else
                {
                    throw new Exception();
                }
                #endregion

                //------

            }
            catch (Exception)
            {
                bandera = false;
            }

            return bandera;
        }
        public ActionResult Crear(MovimientoTemp movimientoTemp)
        {
            db = new RecordFCSContext();

            //Validacion
            if (movimientoTemp.FechaSalida == null)
                ModelState.AddModelError("FechaSalida", "Ingrese una fecha.");

            if (movimientoTemp.UbicacionOrigenID == null)
                ModelState.AddModelError("UbicacionOrigenID", "Seleccione la ubicación.");

            if (movimientoTemp.UbicacionDestinoID == null)
                ModelState.AddModelError("UbicacionDestinoID", "Seleccione la ubicación.");

            var fechaCreacion = DateTime.Now;

            movimientoTemp.FechaUltimaEjecucion = fechaCreacion;
            //Validar ultimo Folioº
            try
            {
                if (ModelState.IsValid)
                {
                    //Crear la entidad
                    movimientoTemp.Folio = db.MovimientosTemp.Select(a => a.Folio).OrderByDescending(a => a).FirstOrDefault() + 1;

                    movimientoTemp.EstadoMovimiento = EstadoMovimientoTemp.Procesando;
                    movimientoTemp.UsuarioID = User.UsuarioID;
                    movimientoTemp.MovimientoTempID = Guid.NewGuid();
                    db.MovimientosTemp.Add(movimientoTemp);

                    //------ Logica HISTORIAL

                    #region Generar el historial

                    // Generar el historial
                    var historialLog =
                        HistorialLogica.CrearEntidad(
                        movimientoTemp,
                        movimientoTemp.GetType().Name,
                        movimientoTemp.MovimientoTempID.ToString(),
                        User.UsuarioID,
                        db,
                        fechaCreacion);

                    #endregion

                    #region Guardar el historial

                    //Guardar cambios si todo salio correcto
                    if (historialLog != null)
                    {
                        //Guardar la entidad
                        db.SaveChanges();

                        //Guardar el historial
                        db.HistorialLogs.Add(historialLog);
                        db.SaveChanges();
                    }
                    else
                    {
                        throw new Exception();
                    }

                    #endregion

                    //------

                    //Logica para terminar la instruccion
                    AlertaSuccess("Se registro el movimiento: <b>" + movimientoTemp.Folio + "</b>", true);

                    return Json(new { success = true, url = Url.Action("Detalles", new { id = movimientoTemp.MovimientoTempID }) });
                }
            }
            catch (Exception)
            {
                ModelState.AddModelError("", "Error desconocido.");
            }

            //Regresar la vista
            var tipoMov = db.TipoMovimientos.Find(movimientoTemp.TipoMovimientoID);

            if (tipoMov == null) return HttpNotFound();

            movimientoTemp.TipoMovimiento = tipoMov;
            movimientoTemp.TipoMovimientoID = tipoMov.TipoMovimientoID;
            movimientoTemp.EsValido = false;
            movimientoTemp.EstadoMovimiento = EstadoMovimientoTemp.Procesando;

            movimientoTemp.Folio = db.MovimientosTemp.Select(a => a.Folio).OrderByDescending(a => a).FirstOrDefault() + 1;

            var listaUbicaciones = db.Ubicaciones.Where(a => a.Status).Select(a => new { a.Nombre, a.UbicacionID }).OrderBy(a => a.Nombre);

            ViewBag.UbicacionDestinoID = new SelectList(listaUbicaciones, "UbicacionID", "Nombre", movimientoTemp.UbicacionDestinoID);
            ViewBag.UbicacionOrigenID = new SelectList(listaUbicaciones, "UbicacionID", "Nombre", movimientoTemp.UbicacionOrigenID);

            return View(movimientoTemp);
        }
        public ActionResult Crear(Guid? TipoMovimientoID, bool TieneExposicion)
        {
            db = new RecordFCSContext();

            var tipoMov = db.TipoMovimientos.Find(TipoMovimientoID);

            if (tipoMov == null) return HttpNotFound();

            var mov = new MovimientoTemp()
            {
                TieneExposicion = TieneExposicion,
                TipoMovimientoID = tipoMov.TipoMovimientoID,
                TipoMovimiento = tipoMov,
                EstadoMovimiento = EstadoMovimientoTemp.Procesando,
                EsValido = false
                //Folio = db.MovimientosTemp.Select(a => a.Folio).OrderBy(a => a).SingleOrDefault() + 1

            };

            mov.Folio = db.MovimientosTemp.Select(a => a.Folio).OrderByDescending(a => a).FirstOrDefault() + 1;

            var listaUbicaciones = db.Ubicaciones.Where(a => a.Status).Select(a => new { a.Nombre, a.UbicacionID }).OrderBy(a => a.Nombre);

            ViewBag.UbicacionDestinoID = new SelectList(listaUbicaciones, "UbicacionID", "Nombre");
            ViewBag.UbicacionOrigenID = new SelectList(listaUbicaciones, "UbicacionID", "Nombre");

            return View(mov);
        }
        private bool Cancelar(MovimientoTemp mov, bool Executar)
        {
            db = new RecordFCSContext();

            bool bandera = false;

            DateTime Fecha = DateTime.Now;
            mov.FechaUltimaEjecucion = Fecha;

            string Motivo = "Cancelar movimiento.";

            try
            {
                bandera = true;

                //Validar que el movimiento se pueda cancelar, comprobando las piezas en estado SeMovio sean las ultimas en su mov
                #region Validacion 3: En ultimo movimiento

                int totalMovidas = mov.MovimientoTempPiezas.Where(a => a.SeMovio).Count();
                int totalMovidasSonUltimas = 0;

                foreach (var piezaEnMovReal in mov.MovimientoTempPiezas.Where(a => a.SeMovio && a.Pieza.UbicacionID == mov.UbicacionDestinoID).ToList())
                    if ((piezaEnMovReal.Pieza.MovimientoTempPiezas.Where(a => a.Orden > piezaEnMovReal.Orden && !a.EnError).Count() > 0))
                        totalMovidasSonUltimas = 0;
                    else
                        totalMovidasSonUltimas++;

                if (totalMovidas != totalMovidasSonUltimas)
                    throw new Exception("No se pueden cancelar las piezas");

                #endregion

                //Revertir todas las piezas
                foreach (var PiezaIDDel in mov.MovimientoTempPiezas.Select(a => a.PiezaID).ToList())
                {
                    bandera = false;
                    //la pieza en el movimiento
                    var item = db.MovimientoTempPiezas.FirstOrDefault(a => a.PiezaID == PiezaIDDel && a.MovimientoTempID == mov.MovimientoTempID);

                    bool RegresarHistorial = false;

                    //saber si es eliminable y si se puede regresar el estado
                    if (item != null)
                    {
                        if (item.SeMovio)
                        {
                            bool esUltimo = item.Pieza.MovimientoTempPiezas.Where(a => a.Orden > item.Orden && !a.EnError).Count() > 0 ? false : true;
                            bool conPendientes = item.Pieza.MovimientoTempPiezas.Where(a => a.EsPendiente && a.MovimientoTempID != mov.MovimientoTempID && !a.EnError).Count() > 0 ? true : false;

                            if (esUltimo)
                                RegresarHistorial = true;
                        }
                        else
                        {
                            RegresarHistorial = true;
                        }
                    }

                    if (RegresarHistorial)
                    {
                        //Regresar la ubicacion original
                        if (item.SeMovio)
                        {
                            var pieza = db.Piezas.Find(PiezaIDDel);

                            RegresarHistorial = false;

                            if (pieza != null)
                            {
                                if (pieza.UbicacionID == mov.UbicacionDestinoID)
                                {
                                    pieza.UbicacionID = mov.UbicacionOrigenID;

                                    //------ Logica HISTORIAL

                                    #region Generar el historial

                                    //objeto del formulario
                                    var objetoDelUbi = pieza;
                                    //Objeto de la base de datos
                                    var objetoDBDelUbi = db.Piezas.Find(pieza.PiezaID);
                                    //tabla o clase a la que pertenece
                                    var tablaNombreDelUbi = "Pieza";
                                    //llave primaria del objeto
                                    var llavePrimariaDelUbi = objetoDBDelUbi.PiezaID.ToString();

                                    //generar el historial
                                    var historialLogDelUbi = HistorialLogica.EditarEntidad(
                                        objetoDelUbi,
                                        objetoDBDelUbi,
                                        tablaNombreDelUbi,
                                        llavePrimariaDelUbi,
                                        User.UsuarioID,
                                        db,
                                        "Cancelar Movimiento: " + mov.Folio,
                                        mov.FechaUltimaEjecucion
                                        );

                                    #endregion

                                    #region Guardar el historial

                                    if (historialLogDelUbi != null)
                                    {
                                        //Cambiar el estado a la entidad a modificada
                                        db.Entry(objetoDBDelUbi).State = EntityState.Modified;
                                        //Guardamos la entidad modificada
                                        db.SaveChanges();

                                        //Guardar el historial
                                        db.HistorialLogs.Add(historialLogDelUbi);
                                        db.SaveChanges();

                                        RegresarHistorial = true;
                                    }

                                    #endregion

                                    //------

                                }

                            }

                        }

                        if (RegresarHistorial)
                        {

                            item.SeMovio = false;
                            item.EsPendiente = true;
                            item.EnError = true;
                            item.Comentario = "Validar de nuevo [Movimiento Cancelado].";

                            //------ Logica HISTORIAL

                            #region Generar el historial

                            //objeto del formulario
                            var objetoEdit = item;
                            //Objeto de la base de datos
                            var objetoDBEdit = db.MovimientoTempPiezas.Find(item.MovimientoTempID, item.PiezaID);
                            //tabla o clase a la que pertenece
                            var tablaNombreEdit = "MovimientoTempPieza";
                            //llave primaria del objeto
                            var llavePrimariaEdit = objetoDBEdit.MovimientoTempID + "," + objetoDBEdit.PiezaID;

                            //generar el historial
                            var historialLogEdit = HistorialLogica.EditarEntidad(
                                objetoEdit,
                                objetoDBEdit,
                                tablaNombreEdit,
                                llavePrimariaEdit,
                                User.UsuarioID,
                                db,
                                Motivo,
                                Fecha
                                );

                            #endregion

                            #region Guardar el historial

                            if (historialLogEdit != null)
                            {
                                //Cambiar el estado a la entidad a modificada
                                db.Entry(objetoDBEdit).State = EntityState.Modified;
                                //Guardamos la entidad modificada
                                db.SaveChanges();

                                //Guardar el historial
                                db.HistorialLogs.Add(historialLogEdit);
                                db.SaveChanges();

                                bandera = true;
                            }
                            else
                            {
                                bandera = true;
                            }

                            #endregion

                            //------

                        }

                    }

                }

                if (bandera)
                {
                    //Como todas las piezas que tenia se revertieron
                    //Regresar el Estatus

                    mov.EstadoMovimiento = EstadoMovimientoTemp.Cancelado;

                    //------ Logica HISTORIAL

                    #region Generar el historial

                    //objeto del formulario
                    var objeto3 = mov;
                    //Objeto de la base de datos
                    var objetoDB3 = db.MovimientosTemp.Find(mov.MovimientoTempID);
                    //tabla o clase a la que pertenece
                    var tablaNombre3 = "MovimientoTemp";
                    //llave primaria del objeto
                    var llavePrimaria3 = objetoDB3.MovimientoTempID.ToString();

                    //generar el historial
                    var historialLog3 = HistorialLogica.EditarEntidad(
                        objeto3,
                        objetoDB3,
                        tablaNombre3,
                        llavePrimaria3,
                        User.UsuarioID,
                        db,
                        Motivo,
                        Fecha
                        );

                    #endregion

                    #region Guardar el historial

                    if (historialLog3 != null)
                    {
                        //Cambiar el estado a la entidad a modificada
                        db.Entry(objetoDB3).State = EntityState.Modified;
                        //Guardamos la entidad modificada
                        db.SaveChanges();

                        //Guardar el historial
                        db.HistorialLogs.Add(historialLog3);
                        db.SaveChanges();
                    }
                    else
                    {
                        throw new Exception();
                    }
                    #endregion

                    //------

                }
            }
            catch (Exception)
            {
                bandera = false;
            }

            if (bandera)
                AlertaDefault("Se Cancelo el moviento");
            else
                AlertaDefault("No se pudo cancelar el movimiento");

            return bandera;
        }
        public ActionResult Index(MovimientoTemp MovTemp = null)
        {
            db = new RecordFCSContext();

            var listaLetras = db.LetraFolios.Select(a => new { a.LetraFolioID, Nombre = a.Nombre, a.Status }).Where(a => a.Status).OrderBy(a => a.Nombre);
            ViewBag.LetraFolioID = new SelectList(listaLetras, "LetraFolioID", "Nombre", listaLetras.FirstOrDefault().LetraFolioID);

            var listaUbicaciones = db.Ubicaciones.Where(a => a.Status).Select(a => new { a.Nombre, a.UbicacionID }).OrderBy(a => a.Nombre);

            ViewBag.UbicacionDestinoID = new SelectList(listaUbicaciones, "UbicacionID", "Nombre");
            ViewBag.UbicacionOrigenID = new SelectList(listaUbicaciones, "UbicacionID", "Nombre");

            ViewBag.TipoMovimientoID = new SelectList(db.TipoMovimientos.Where(a => a.Status).OrderBy(a => a.Nombre), "TipoMovimientoID", "Nombre", MovTemp.TipoMovimientoID);

            if (MovTemp == null)
            {
                MovTemp = new MovimientoTemp()
                {
                    TieneExposicion = false,
                    EstadoMovimiento = null
                };
            }

            return View(MovTemp);
        }
        private bool RevertirMovimiento(MovimientoTemp mov)
        {
            bool bandera = false;

            DateTime Fecha = mov.FechaUltimaEjecucion.Value;
            string Motivo = "Revertir movimiento.";

            try
            {

                bandera = true;

                //Revertir las piezas que estan en el estado SeMovio
                foreach (var PiezaIDDel in mov.MovimientoTempPiezas.Where(a => a.SeMovio).Select(a => a.PiezaID).ToList())
                {
                    bandera = false;
                    //la pieza en el movimiento
                    var item = db.MovimientoTempPiezas.FirstOrDefault(a => a.PiezaID == PiezaIDDel && a.MovimientoTempID == mov.MovimientoTempID);

                    bool RegresarHistorial = false;

                    //saber si es eliminable y si se puede regresar el estado
                    if (item != null)
                    {
                        bool esUltimo = item.Pieza.MovimientoTempPiezas.Where(a => a.Orden > item.Orden && !a.EnError).Count() > 0 ? false : true;
                        bool conPendientes = item.Pieza.MovimientoTempPiezas.Where(a => a.EsPendiente && a.MovimientoTempID != mov.MovimientoTempID && !a.EnError).Count() > 0 ? true : false;

                        if (item.SeMovio && esUltimo)
                            RegresarHistorial = true;

                    }

                    if (RegresarHistorial)
                    {
                        var pieza = db.Piezas.Find(PiezaIDDel);

                        RegresarHistorial = false;

                        if (pieza != null)
                        {
                            if (pieza.UbicacionID == mov.UbicacionDestinoID)
                            {
                                pieza.UbicacionID = mov.UbicacionOrigenID;

                                //------ Logica HISTORIAL

                                #region Generar el historial

                                //objeto del formulario
                                var objetoDelUbi = pieza;
                                //Objeto de la base de datos
                                var objetoDBDelUbi = db.Piezas.Find(pieza.PiezaID);
                                //tabla o clase a la que pertenece
                                var tablaNombreDelUbi = "Pieza";
                                //llave primaria del objeto
                                var llavePrimariaDelUbi = objetoDBDelUbi.PiezaID.ToString();

                                //generar el historial
                                var historialLogDelUbi = HistorialLogica.EditarEntidad(
                                    objetoDelUbi,
                                    objetoDBDelUbi,
                                    tablaNombreDelUbi,
                                    llavePrimariaDelUbi,
                                    UsuarioID,
                                    db,
                                    "Retornar Movimiento: " + mov.Folio,
                                    mov.FechaUltimaEjecucion
                                    );

                                #endregion

                                #region Guardar el historial

                                if (historialLogDelUbi != null)
                                {
                                    //Cambiar el estado a la entidad a modificada
                                    db.Entry(objetoDBDelUbi).State = EntityState.Modified;
                                    //Guardamos la entidad modificada
                                    db.SaveChanges();

                                    //Guardar el historial
                                    db.HistorialLogs.Add(historialLogDelUbi);
                                    db.SaveChanges();

                                    RegresarHistorial = true;
                                }

                                #endregion

                                //------

                            }

                        }

                        if (RegresarHistorial)
                        {

                            item.SeMovio = false;
                            item.EsPendiente = true;
                            item.EnError = true;
                            item.Comentario = "Validar de nuevo [Movimiento Revertido].";

                            //------ Logica HISTORIAL

                            #region Generar el historial

                            //objeto del formulario
                            var objetoEdit = item;
                            //Objeto de la base de datos
                            var objetoDBEdit = db.MovimientoTempPiezas.Find(item.MovimientoTempID, item.PiezaID);
                            //tabla o clase a la que pertenece
                            var tablaNombreEdit = "MovimientoTempPieza";
                            //llave primaria del objeto
                            var llavePrimariaEdit = objetoDBEdit.MovimientoTempID + "," + objetoDBEdit.PiezaID;

                            //generar el historial
                            var historialLogEdit = HistorialLogica.EditarEntidad(
                                objetoEdit,
                                objetoDBEdit,
                                tablaNombreEdit,
                                llavePrimariaEdit,
                                UsuarioID,
                                db,
                                Motivo,
                                mov.FechaUltimaEjecucion
                                );

                            #endregion

                            #region Guardar el historial

                            if (historialLogEdit != null)
                            {
                                //Cambiar el estado a la entidad a modificada
                                db.Entry(objetoDBEdit).State = EntityState.Modified;
                                //Guardamos la entidad modificada
                                db.SaveChanges();

                                //Guardar el historial
                                db.HistorialLogs.Add(historialLogEdit);
                                db.SaveChanges();

                                bandera = true;
                            }

                            #endregion

                            //------

                        }

                    }

                }

                if (bandera)
                {
                    //Como todas las piezas que tenia se revertieron
                    //REgresar el Estatus

                    mov.EstadoMovimiento = EstadoMovimientoTemp.Retornado;

                    //------ Logica HISTORIAL

                    #region Generar el historial

                    //objeto del formulario
                    var objeto3 = mov;
                    //Objeto de la base de datos
                    var objetoDB3 = db.MovimientosTemp.Find(mov.MovimientoTempID);
                    //tabla o clase a la que pertenece
                    var tablaNombre3 = "MovimientoTemp";
                    //llave primaria del objeto
                    var llavePrimaria3 = objetoDB3.MovimientoTempID.ToString();

                    //generar el historial
                    var historialLog3 = HistorialLogica.EditarEntidad(
                        objeto3,
                        objetoDB3,
                        tablaNombre3,
                        llavePrimaria3,
                        UsuarioID,
                        db,
                        Motivo + "[Automatico]",
                        Fecha
                        );

                    #endregion

                    #region Guardar el historial

                    if (historialLog3 != null)
                    {
                        //Cambiar el estado a la entidad a modificada
                        db.Entry(objetoDB3).State = EntityState.Modified;
                        //Guardamos la entidad modificada
                        db.SaveChanges();

                        //Guardar el historial
                        db.HistorialLogs.Add(historialLog3);
                        db.SaveChanges();
                    }
                    else
                    {
                        throw new Exception();
                    }
                    #endregion

                    //------

                }

            }
            catch (Exception)
            {
                bandera = false;
            }

            return bandera;
        }
        private bool GuardarErrorEnMovimiento(MovimientoTemp mov, string Error)
        {
            bool bandera = false;

            DateTime Fecha = mov.FechaUltimaEjecucion.Value;

            //------ Logica HISTORIAL

            #region Generar el historial

            //objeto del formulario
            var objeto3 = mov;
            //Objeto de la base de datos
            var objetoDB3 = db.MovimientosTemp.Find(mov.MovimientoTempID);
            //tabla o clase a la que pertenece
            var tablaNombre3 = "MovimientoTemp";
            //llave primaria del objeto
            var llavePrimaria3 = objetoDB3.MovimientoTempID.ToString();

            //generar el historial
            var historialLog3 = HistorialLogica.EditarEntidad(
                objeto3,
                objetoDB3,
                tablaNombre3,
                llavePrimaria3,
                UsuarioID,
                db,
                Error,
                Fecha
                );

            #endregion

            #region Guardar el historial

            if (historialLog3 != null)
            {
                //Cambiar el estado a la entidad a modificada
                db.Entry(objetoDB3).State = EntityState.Modified;
                //Guardamos la entidad modificada
                db.SaveChanges();

                //Guardar el historial
                db.HistorialLogs.Add(historialLog3);
                db.SaveChanges();

                bandera = true;
            }
            else
            {
                bandera = false;
            }
            #endregion

            //------

            return bandera;
        }