public static List<Funcionalidad> GetByRole(Rol role, SqlTransaction transaction)
        {
            //Obtengo todas las funcionalidades asociadas a determinado rol (transaccionado)
            var param = new List<SPParameter> { new SPParameter("ID_Rol", role.ID) };
            var sp = new StoreProcedure(DataBaseConst.Funcionalidad.SPGetAllFuncionalidadByRol, param, transaction);

            //Retorno una lista de Funcionalidad a partir de un ExecuteReader transaccionado
            return sp.ExecuteReaderTransactioned<Funcionalidad>(transaction);
        }
        public FrmABMInsertUpdateRol(Rol role)
        {
            InitializeComponent();

            //Si no se le pasa ningún rol por parámetro (NULL) se considera que esta trabajando en modo alta
            insertMode = role == null;

            if (!insertMode)
                CurrentRole = role;
        }
        public static int DeleteByRole(Rol role, SqlTransaction transaction)
        {
            var param = new List<SPParameter> { new SPParameter("ID_Rol", role.ID) };
            var sp = (transaction != null)
                            ? new StoreProcedure(DataBaseConst.Rol.SPDeleteAllFuncionalidadByRol, param, transaction)
                            : new StoreProcedure(DataBaseConst.Rol.SPDeleteAllFuncionalidadByRol, param);

            //Retorno la cantidad de funcionalidades eliminadas a partir de un ExecuteNonQuery
            return sp.ExecuteNonQuery(transaction);
        }
        public static Rol Insert(Rol role, SqlTransaction transaction)
        {
            var param = new List<SPParameter>
                {
                    new SPParameter("Descripcion", role.Descripcion),
                    new SPParameter("Activo", role.Activo)
                };

            var sp = (transaction != null)
                        ? new StoreProcedure(DataBaseConst.Rol.SPInsertRol, param, transaction)
                        : new StoreProcedure(DataBaseConst.Rol.SPInsertRol, param);

            role.ID = (int)sp.ExecuteScalar(transaction);

            return role;
        }
        public static int InsertByRole(Rol role, SqlTransaction transaction)
        {
            var regsAffected = 0;

            foreach (var feature in role.Funcionalidades)
            {
                var param = new List<SPParameter> { new SPParameter("ID_Funcionalidad", feature.ID), new SPParameter("ID_Rol", role.ID) };
                var sp = (transaction != null)
                            ? new StoreProcedure(DataBaseConst.Rol.SPInsertFuncionalidadByRol, param, transaction)
                            : new StoreProcedure(DataBaseConst.Rol.SPInsertFuncionalidadByRol, param);

                regsAffected += sp.ExecuteNonQuery(transaction);
            }

            //Retorno la cantidad de funcionalidades insertadas a partir de un ExecuteNonQuery
            return regsAffected;
        }
        public static void InsertRoleAndFeatures(Rol role)
        {
            /* Lo tengo que hacer transaccionado ya que no quiero que pueda llegar a quedar un rol insertado
            sin las funcionalidades asociadas debido a un error */
            using (var transaction = DataBaseManager.Instance().Connection.BeginTransaction(IsolationLevel.Serializable))
            {
                try
                {
                    role = Insert(role, transaction);
                    FuncionalidadPersistance.InsertByRole(role, transaction);

                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new Exception("Se produjo un error durante la insercion del rol");
                }
            }
        }
        private void LblGrabar_Click(object sender, EventArgs e)
        {
            try
            {
                #region Validations

                var exceptionMessage = string.Empty;

                if (string.IsNullOrEmpty(TxtRol.Text))
                    exceptionMessage += "El nombre del rol no puede ser vacío.";

                if (LstFuncionalidades.CheckedItems.Count == 0)
                    exceptionMessage += Environment.NewLine +  "Debe seleccionar por lo menos una funcionalidad.";

                if (!string.IsNullOrEmpty(exceptionMessage))
                    throw new Exception(exceptionMessage);

                #endregion

                if (insertMode)
                {
                    //Valido que no exista un rol con la descripcion informada
                    if (RolPersistance.GetByName(TxtRol.Text) != null)
                        throw new Exception("Ya existe un rol con el nombre ingresado.");

                    #region Inserto el rol con sus funcionalidades

                    var role = new Rol();
                    role.Activo = ChkActivo.Checked;
                    role.Descripcion = TxtRol.Text;

                    //A partir de los items chequeados, seteo las funcionalidades del objeto a insertar
                    foreach (var checkedItem in LstFuncionalidades.CheckedItems)
                    {
                        var feature = (Funcionalidad)checkedItem;
                        role.Funcionalidades.Add(feature);
                    }

                    var dialogAnswer = MessageBox.Show("Esta seguro que quiere insertar el nuevo rol?", "Atencion", MessageBoxButtons.YesNo);
                    if (dialogAnswer == DialogResult.Yes)
                    {
                        //Impacto en la base
                        RolPersistance.InsertRoleAndFeatures(role);
                        CompleteAction = true;
                        Close();
                    }

                    #endregion
                }
                else
                {
                    #region Modifico un rol existente y sus funcionalidades

                    CurrentRole.Activo = ChkActivo.Checked;
                    CurrentRole.Descripcion = TxtRol.Text;
                    CurrentRole.Funcionalidades = new List<Funcionalidad>();

                    //A partir de los items chequeados, seteo las funcionalidades del objeto a insertar
                    foreach (var checkedItem in LstFuncionalidades.CheckedItems)
                    {
                        var feature = (Funcionalidad)checkedItem;
                        CurrentRole.Funcionalidades.Add(feature);
                    }

                    var dialogAnswer = MessageBox.Show(string.Format("Esta seguro que quiere modificar el rol {0}?", CurrentRole.Descripcion), "Atencion", MessageBoxButtons.YesNo);
                    if (dialogAnswer == DialogResult.Yes)
                    {
                        //Impacto en la base
                        RolPersistance.UpdateRoleAndFeatures(CurrentRole);
                        CompleteAction = true;
                        Close();
                    }

                    #endregion
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Atención");
            }
        }
        public static void UpdateRoleAndFeatures(Rol role)
        {
            /* Lo tengo que hacer transaccionado ya que no quiero que pueda llegar a quedar un rol insertado
            sin las funcionalidades asociadas debido a un error */
            using (var transaction = DataBaseManager.Instance().Connection.BeginTransaction(IsolationLevel.Serializable))
            {
                try
                {
                    Update(role, transaction);

                    if (FuncionalidadPersistance.DeleteByRole(role, transaction) > 0)
                        if (FuncionalidadPersistance.InsertByRole(role, transaction) > 0)
                            //La unica forma que se realice la transaction: borro todas las funcionalidades viejas e inserto las nuevas
                            transaction.Commit();
                        else
                            //Tuvo que haber insertado por lo menos una, sino es un error
                            transaction.Rollback();
                    else
                        //Tuvo que haber insertado por lo menos una, sino es un error
                        transaction.Rollback();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new Exception("Se produjo un error durante la modificacion del rol");
                }
            }
        }
        public static int Update(Rol role, SqlTransaction transaction)
        {
            var param = new List<SPParameter>
                {
                    new SPParameter("ID_Rol", role.ID),
                    new SPParameter("Descripcion", role.Descripcion),
                    new SPParameter("Activo", role.Activo)
                };

            var sp = (transaction != null)
                        ? new StoreProcedure(DataBaseConst.Rol.SPUpdateRolById, param, transaction)
                        : new StoreProcedure(DataBaseConst.Rol.SPUpdateRolById, param);

            return sp.ExecuteNonQuery(transaction);
        }
        public static int InsertUserRole(Usuario user, Rol role, SqlTransaction transaction)
        {
            var param = new List<SPParameter>
                {
                    new SPParameter("ID_Usuario", user.ID),
                    new SPParameter("ID_Rol", role.ID)
                };

            var sp = (transaction != null)
                        ? new StoreProcedure(DataBaseConst.Rol.SPInsertUserRole, param, transaction)
                        : new StoreProcedure(DataBaseConst.Rol.SPInsertUserRole, param);

            return sp.ExecuteNonQuery(transaction);
        }