private void RecuperarInformacion_ExecuteCode(object sender, EventArgs e)
        {
            itemOC = workflowProperties.Item;

            try
            {
                autonomina = this.VerificarAutonomia();

                if (autonomina)
                {
                    #region Aprobar automaticamente el item
                    SPModerationInformation estadoAprobacion = itemOC.ModerationInformation;
                    estadoAprobacion.Status = SPModerationStatusType.Approved;

                    using (DisabledItemEventsScope scope = new DisabledItemEventsScope())
                    {//Para evitar que ejecute una y otra vez el Evento ItemUpdating sobre este item
                        itemOC.SystemUpdate();
                    }
                    #endregion

                    #region Actualizar bitacora
                    //EjecutorOperacionesSP.ActualizarBitacoraAprobacion(itemOC);
                    #endregion

                    #region Notificacion por correo
                    asuntoNotificacion  = "Abastecimiento, orden de compra aprobada";
                    cuerpoNotificacion  = this.CuerpoCorreoNotificacion();
                    usuariosNotificados = this.UsuariosANotificar();
                    usuariosCopiados    = this.UsuariosACopiar();
                    mensajeHistorial    = "Notificación por aprobación automática realizada exitosamente.";
                    #endregion

                    #region Iniciar el flujo 'Notificar Descuentos'
                    EjecutorOperacionesSP.IniciarFlujoNotificarDescuentos(itemOC);
                    #endregion
                }
                else
                {
                    #region Notificacion por correo
                    asuntoNotificacion  = "Abastecimiento, solictud de aprobación";
                    cuerpoNotificacion  = this.CuerpoCorreoSolicitud();
                    usuariosNotificados = this.UsuariosANotificar();
                    //usuariosCopiados = this.UsuariosACopiar();
                    mensajeHistorial = "Notificación a 'Aprobadores de OC' realizada exitosamente.";
                    #endregion
                }
            }
            catch (Exception ex)
            {
                #region Registro de Evento Error
                LogEventos.LogArchivo log = new LogEventos.LogArchivo("LogErrores.txt");
                log.WriteEvent("--- [FLUJO] RecuperarInformacion_ExecuteCode flujo 'Notificar aprobación' ---");
                log.WriteException(ex);
                #endregion

                logNotificarAprobacion.EventId            = SPWorkflowHistoryEventType.WorkflowError;
                logNotificarAprobacion.HistoryOutcome     = "Error";
                logNotificarAprobacion.HistoryDescription = ex.Message;
            }
        }
        /// <summary>
        /// Genera el Envío asociado para los ítems pedidos en la OC.
        /// Adicionalmente, tambien genera la Factura que se asocia al Envío generado.
        /// </summary>
        private void GenerarEnvioParaOC()
        {
            int idOrden = Convert.ToInt32(this.IDOrdenCompra.Value);

            string tipoEnvio = null;

            if (ddlTipoEnvio.SelectedValue != "")
            {
                tipoEnvio = ddlTipoEnvio.SelectedValue;
            }

            if (tipoEnvio != null)
            {
                EjecutorOperacionesSP.InsertarEnvioParaOC(tipoEnvio, idOrden);
            }
        }
        //private string GRUPO_PROPIETARIOS = "Propietarios Abastecimiento XEROBOL";
        //private string GRUPO_APROBADORES = "Aprobadores de OC";

        /// <summary>
        /// An item is being added.
        /// </summary>
        public override void ItemAdding(SPItemEventProperties properties)
        {
            //base.ItemAdding(properties);
            try
            {
                #region Evento lista 'Envíos'
                if (properties.ListTitle == LISTA_ENVIOS)
                {
                    #region Validar ítems pedidos validos para envio
                    List <string> itemsNoValidos =
                        EjecutorOperacionesSP.RecuperarItemsPedidosNoValidosParaEnvio(properties);

                    //Validar si la urgencia del ítem pedido corresponde o no al tipo de envio definido
                    if (itemsNoValidos.Count != 0)
                    {
                        string linksItems = "";

                        foreach (string itemNoValido in itemsNoValidos)
                        {
                            linksItems += itemNoValido + "<br/>";
                        }

                        properties.Status       = SPEventReceiverStatus.CancelWithError;
                        properties.ErrorMessage =
                            string.Format("Los ítems siguientes no pueden ser asociados al " +
                                          "tipo de envío elegido:<br/>{0}<br/><br/>Vuelva a la página anterior " +
                                          "y seleccione otro tipo de envío.", linksItems);
                        properties.Cancel = true;
                    }
                    #endregion
                }
                #endregion
            }
            catch (Exception ex)
            {
                #region Registro de Evento Error
                LogEventos.LogArchivo log = new LogEventos.LogArchivo("LogErrores.txt");
                log.WriteEvent("--- [EVENTO] ItemAdding ---");
                log.WriteException(ex);
                #endregion

                properties.Status       = SPEventReceiverStatus.CancelWithError;
                properties.ErrorMessage = ex.Message;
                properties.Cancel       = true;
            }
        }
        /// <summary>
        /// Actualiza la fila seleccionada del grid grvItemsPedidos
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="row"></param>
        private void ActualizarItemPedido(int itemId, GridViewRow row)
        {
            NumberField fCantidad = (NumberField)row.FindControl("numCantidad");
            NumberField fPrecioU  = (NumberField)row.FindControl("numPrecioUnitario");
            //LookupField fMoneda = (LookupField)row.FindControl("lufMonedaItem");
            NumberField fPeso            = (NumberField)row.FindControl("numPeso");
            LookupField fUnidadM         = (LookupField)row.FindControl("lufUnidadMedida");
            TextField   fDims            = (TextField)row.FindControl("txtDimensiones");
            LookupField fCliente         = (LookupField)row.FindControl("lufCliente");
            LookupField fClienteAsociado = (LookupField)row.FindControl("lufClienteAsociado");
            LookupField fTipoPedido      = (LookupField)row.FindControl("lufTipoPedido");

            string cantidad = fCantidad.Value.ToString();
            string precioU  = fPrecioU.Value.ToString();
            //string moneda = fMoneda.Value.ToString();
            string peso = "";

            if (fPeso.Value != null)
            {
                peso = fPeso.Value.ToString();
            }
            string unidadM = "";

            if (fUnidadM.Value != null)
            {
                unidadM = fUnidadM.Value.ToString();
            }
            string dims = "";

            if (fDims.Value != null)
            {
                dims = fDims.Value.ToString();
            }
            string cliente         = fCliente.Value.ToString();
            string clienteAsociado = "";

            if (fClienteAsociado.Value != null)
            {
                clienteAsociado = fClienteAsociado.Value.ToString();
            }
            string tipoPedido = fTipoPedido.Value.ToString();

            EjecutorOperacionesSP.ActualizarItemPedido(itemId, cantidad, precioU,
                                                       peso, unidadM, dims, cliente, tipoPedido, clienteAsociado);
        }
        /// <summary>
        /// Guardar nuevo ítem asociado a la OC
        /// </summary>
        private void InsertarItemPedido()
        {
            //string ocAsociada = this.Request.QueryString["oc"];
            //int itemId = Convert.ToInt32(this.IDItemPedido.Value);

            string ocAsociada   = this.IDOrdenCompra.Value;
            string titulo       = ddlItemAsociado.SelectedItem.Text;
            string itemAsociado = ddlItemAsociado.SelectedItem.Value;
            string cantidad     = numCantidad.Value.ToString();
            string precioU      = numPrecioUnitario.Value.ToString();
            //string moneda = lufMonedaItem.Value.ToString();
            string peso = "";

            if (numPeso.Value != null)
            {
                peso = numPeso.Value.ToString();
            }
            string unidadM = "";

            if (lufUnidadMedida.Value != null)
            {
                unidadM = lufUnidadMedida.Value.ToString();
            }
            string dims = "";

            if (txtDimensiones.Value != null)
            {
                dims = txtDimensiones.Value.ToString();
            }
            string cliente         = lufCliente.Value.ToString();
            string clienteAsociado = "";

            if (lufClienteAsociado.Value != null)
            {
                clienteAsociado = lufClienteAsociado.Value.ToString();
            }
            string tipoPedido = lufTipoPedido.Value.ToString();

            EjecutorOperacionesSP.InsertarItemPedido(itemAsociado, ocAsociada, titulo, cantidad,
                                                     precioU, peso, unidadM, dims, cliente, tipoPedido, clienteAsociado);
        }
        /// <summary>
        /// Guardar (como nuevo) o actualizar un item de la lista 'Órdenes de Compra Internas'
        /// </summary>
        private void GuardarOrdenCompra(string sender)
        {
            int idOrden = Convert.ToInt32(this.IDOrdenCompra.Value);

            string titulo          = txtTitulo.Text;
            string fechaSolicitada = dtfFechaSolicitada.Value.ToString();
            string observaciones   = txtObservaciones.Text;
            string precioTotal     = this.PrecioTotalOC.Value;
            string moneda          = null;

            if (lufMoneda.Value != null)
            {
                moneda = lufMoneda.Value.ToString();
            }

            int itemId = EjecutorOperacionesSP.ActualizarOC(idOrden, titulo, fechaSolicitada,
                                                            observaciones, precioTotal, moneda, sender);

            if (itemId == 0)
            {//Se asigna el ID del item creado a la variable de tipo HiddenField
                this.IDOrdenCompra.Value =
                    EjecutorOperacionesSP.InsertarOC(titulo, fechaSolicitada, observaciones).ToString();
            }
        }
        /*protected void grvItemsPedidos_RowDeleting(object sender, GridViewDeleteEventArgs e)
         * {
         *  int itemId = Convert.ToInt32(grvItemsPedidos.DataKeys[e.RowIndex].Value.ToString());
         *
         *  EjecutorOperacionesSP.EliminarItemPedido(itemId);
         * }*/

        protected void ddlItemAsociado_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(ddlItemAsociado.SelectedValue))
            {
                List <string> precioYMoneda =
                    EjecutorOperacionesSP.RecuperarPrecioYMonedaItem(Convert.ToInt32(ddlItemAsociado.SelectedValue));

                if (!string.IsNullOrEmpty(precioYMoneda[0]))
                {
                    numPrecioUnitario.Value = double.Parse(precioYMoneda[0], new CultureInfo("es-BO"));
                }
                else
                {
                    numPrecioUnitario.Value = precioYMoneda[0];
                }

                //lufMonedaItem.Value = precioYMoneda[1];
            }
            else
            {
                numPrecioUnitario.Value = "";
                //lufMonedaItem.Value = "";
            }
        }
        /// <summary>
        /// Formatea el cuerpo del correo con información sobre descuentos
        /// </summary>
        /// <returns></returns>
        private string CuerpoCorreoNotificacion()
        {
            string urlItemDescuentos = workflowProperties.Web.Url +
                                       workflowProperties.Web.Lists[LISTA_DESCUENTOS].DefaultDisplayFormUrl + "?ID=";
            string urlListaDescuentos = workflowProperties.Web.Url +
                                        workflowProperties.Web.Lists[LISTA_DESCUENTOS].DefaultViewUrl;
            string urlItemOC = workflowProperties.Web.Url +
                               workflowProperties.List.DefaultDisplayFormUrl + "?ID=";

            #region Formatear items
            SPListItemCollection itemsDescuentos =
                workflowProperties.Web.Lists[LISTA_DESCUENTOS].Items;
            SPListItemCollection itemsPedidos =
                EjecutorOperacionesSP.RecuperarItemsPedidosAsociados(itemObjetivo.ID, itemObjetivo.Web);//TODO Probar descuentos

            string formatoItems = "";
            foreach (SPListItem itemPedido in itemsPedidos)
            {
                bool   tieneDescuento    = false;
                string formatoDescuentos = "";
                foreach (SPListItem itemDescuento in itemsDescuentos)
                {
                    if (itemPedido["Ítem asociado"].ToString() == itemDescuento["Ítem asociado"].ToString())
                    {
                        tieneDescuento    = true;
                        formatoDescuentos = formatoDescuentos +
                                            string.Format("<li><a href='{0}'>{1}</a> - {2}</li>",
                                                          urlItemDescuentos + itemDescuento.ID, itemDescuento.Title,
                                                          this.FormatoSubcadena(itemDescuento["Proveedor asociado"]));
                    }
                }

                if (tieneDescuento)
                {
                    formatoDescuentos = "<ul style='list-style-type:none'>" + formatoDescuentos + "</ul>";
                    formatoItems      = formatoItems +
                                        string.Format("<li><b>{0}</b>{1}</li>", this.FormatoSubcadena(itemPedido["Ítem asociado"]),
                                                      formatoDescuentos);
                }
            }

            if (formatoItems != "")
            {
                formatoItems = "<ul style='margin-left:15px'>" + formatoItems + "</ul>";
            }
            else
            {
                formatoItems = "<i>No existen descuentos asociados a los ítems pedidos en la OC indicada.</i>";
            }
            #endregion

            #region Formatear todo el cuerpo
            string cuerpoCorreo = string.Format(
                "<table border='0' cellspacing='0' cellpadding='0' width='100%' style='width:100%;border-collapse:collapse;'>" +
                "<tr><td style='border:solid #E8EAEC 1.0pt;background:#F8F8F9;padding:12.0pt 7.5pt 15.0pt 7.5pt'>" +
                "<p style='font-size:15.0pt;font-family:Verdana,sans-serif;'>" +
                "Sistema de Abastecimiento: Items con descuentos de la OC <a href='{0}'>{1}</a></p></td></tr>" +
                "<tr><td style='border:none;border-bottom:solid #9CA3AD 1.0pt;padding:4.0pt 7.5pt 4.0pt 7.5pt'>" +
                "<p style='font-size:10.0pt;font-family:Tahoma,sans-serif'>" +
                "A continuación se listan los descuentos aplicables a la Orden de Compra '{1}' (ID: <b>{2}</b>). " +
                "Puede navegar a la página de <a href='{3}'>{4}</a> para ver la lista de todos los descuentos aplicables, " +
                "o puede seguir el enlace asociado a cada ítem para tener un detalle de cada descuento.</p>" +
                formatoItems +
                "<p style='font-size:8.0pt;font-family:Tahoma,sans-serif;'>" +
                "Última modificación realizada por {5} en fecha {6}</p></td></tr></table>",
                urlItemOC + itemObjetivo.ID, itemObjetivo.Title, itemObjetivo.ID, urlListaDescuentos,
                workflowProperties.Web.Lists[LISTA_DESCUENTOS].Title, this.FormatoSubcadena(itemObjetivo["Modificado por"]),
                Convert.ToDateTime(itemObjetivo["Modificado"].ToString()).ToString("dd/MM/yyyy HH:mm"));
            #endregion

            return(cuerpoCorreo);
        }
        /// <summary>
        /// An item is being updated.
        /// </summary>
        public override void ItemUpdating(SPItemEventProperties properties)
        {
            //base.ItemUpdating(properties);
            try
            {
                #region Evento lista 'Órdenes de Compra Internas'
                if (properties.ListTitle == LISTA_OCI)
                {
                    #region Permitir edicion de la OC
                    //string creadoPor = EjecutorOperacionesSP.SubcadenaAntes(properties.ListItem["Creado por"]);

                    //if (properties.CurrentUserId != Convert.ToInt32(creadoPor) &&
                    //    !properties.Web.Groups[GRUPO_PROPIETARIOS].ContainsCurrentUser &&
                    //    !properties.Web.Groups[GRUPO_APROBADORES].ContainsCurrentUser)
                    //{
                    //    properties.Status = SPEventReceiverStatus.CancelWithError;
                    //    properties.ErrorMessage = "Solo el usuario creador (" +
                    //        EjecutorOperacionesSP.SubcadenaDespues(properties.ListItem["Creado por"]) + ") " +
                    //        "tiene permitido modificar esta orden de compra.";
                    //    properties.Cancel = true;

                    //    return;
                    //}
                    #endregion

                    #region Negar edición de 'Precio total'
                    if (properties.AfterProperties["Precio_x0020_total"] != null)
                    {
                        string precioAntes =
                            properties.ListItem["Precio_x0020_total"].ToString();
                        string precioDespues =
                            properties.AfterProperties["Precio_x0020_total"].ToString().Replace('.', ',');

                        if (precioDespues != precioAntes)
                        {
                            properties.Status       = SPEventReceiverStatus.CancelWithError;
                            properties.ErrorMessage = "El campo 'Precio total' no puede ser modificado directamente. " +
                                                      "Este campo es auto-calculado en base a los ítems pedidos asociados a esta OC.";
                            properties.Cancel = true;

                            return;
                        }
                    }
                    #endregion

                    #region Generar Codigo XBOL y actualizar descuentos
                    //TODO Cambiar

                    /*OJO tal vez se tenga que quitar. O ponerlo en la lista 'Órdenes de Compra Proveedor'
                     * EjecutorOperacionesSP.ActualizarCodigoXbolYDescuentos(properties);
                     */
                    #endregion
                }
                #endregion

                #region Evento lista 'Envíos'
                if (properties.ListTitle == LISTA_ENVIOS)
                {
                    #region Validar ítems pedidos validos para envio
                    List <string> itemsNoValidos =
                        EjecutorOperacionesSP.RecuperarItemsPedidosNoValidosParaEnvio(properties);

                    //Validar si la urgencia del ítem pedido corresponde o no al tipo de envio definido
                    if (itemsNoValidos.Count != 0)
                    {
                        string linksItems = "";

                        foreach (string itemNoValido in itemsNoValidos)
                        {
                            linksItems += itemNoValido + "<br/>";
                        }

                        properties.Status       = SPEventReceiverStatus.CancelWithError;
                        properties.ErrorMessage =
                            string.Format("Los ítems siguientes no pueden ser asociados al " +
                                          "tipo de envío elegido:<br/>{0}<br/><br/>Vuelva a la página anterior " +
                                          "y seleccione otro tipo de envío.", linksItems);
                        properties.Cancel = true;
                    }
                    #endregion
                }
                #endregion
            }
            catch (Exception ex)
            {
                #region Registro de Evento Error
                LogEventos.LogArchivo log = new LogEventos.LogArchivo("LogErrores.txt");
                log.WriteEvent("--- [EVENTO] ItemUpdating ---");
                log.WriteException(ex);
                #endregion

                properties.Status       = SPEventReceiverStatus.CancelWithError;
                properties.ErrorMessage = ex.Message;
                properties.Cancel       = true;
            }
        }
        /// <summary>
        /// An item was updated.
        /// </summary>
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            //base.ItemUpdated(properties);
            try
            {
                #region Eventos de lista 'Ítems Pedidos'
                if (properties.ListTitle == LISTA_ITEMS_PEDIDOS)
                {
                    EjecutorOperacionesSP.ActualizarCamposOcultos(properties.ListItem);
                    EjecutorOperacionesSP.DeseleccionarItemAsociadoDeFacturas(properties);
                    EjecutorOperacionesSP.DeseleccionarItemOrdenadoDeOCPs(properties);
                    EjecutorOperacionesSP.ActualizarCamposDePreciosTotales(properties);

                    /*try { EjecutorOperacionesSP.ActualizarBitacoraEstados(properties); }
                     * catch { }*/
                }
                #endregion

                #region Eventos de lista 'Órdenes de Compra Internas'
                if (properties.ListTitle == LISTA_OCI)
                {
                    EjecutorOperacionesSP.AprobarAutomaticamente(properties.ListItem);
                    EjecutorOperacionesSP.IniciarFlujoNotificarDescuentos(properties.ListItem);

                    /*try { EjecutorOperacionesSP.ActualizarBitacoraAprobacion(properties.ListItem); }
                     * catch { }*/
                }
                #endregion

                #region Eventos de lista 'Envíos'
                if (properties.ListTitle == LISTA_ENVIOS)
                {
                    EjecutorOperacionesSP.SincronizarAlmacenesAsociadosDeEnvio(properties);
                    EjecutorOperacionesSP.SincronizarFechaPrevistaLlegada(properties);
                    EjecutorOperacionesSP.CambiarCampoParaFiltro_Asignado_Env(properties);
                }
                #endregion

                #region Eventos de lista 'Facturas'
                if (properties.ListTitle == LISTA_FACTURAS)
                {
                    EjecutorOperacionesSP.SincronizarItemsAsociadosDeFactura(properties);
                    EjecutorOperacionesSP.DeseleccionarFacturaDeAlmacenes(properties);
                    EjecutorOperacionesSP.CalcularCampoTotalFactura(properties.ListItem);
                    EjecutorOperacionesSP.CambiarCampoParaFiltro_Asignado_Fac(properties);
                }
                #endregion

                #region Eventos de lista 'Almacén'
                if (properties.ListTitle == LISTA_ALMACEN)
                {
                    EjecutorOperacionesSP.SincronizarFacturasAsociadasDeAlmacen(properties);
                    EjecutorOperacionesSP.DeseleccionarAlmacenDeEnvios(properties);
                    EjecutorOperacionesSP.CalcularCampoTotalFacturas(properties.ListItem);
                    EjecutorOperacionesSP.CambiarCampoParaFiltro_Asignada_Alm(properties);
                }
                #endregion

                #region Eventos de Órdenes de Compra Proveedor
                if (properties.ListTitle == LISTA_OCP)
                {
                    EjecutorOperacionesSP.SincronizarItemsAsociadosDeOCP(properties);
                    EjecutorOperacionesSP.CambiarCampoParaFiltro_Asignado_OCP(properties);
                }
                #endregion

                #region Eventos de lista Documentos Legales
                if (properties.ListTitle == LISTA_DOCUMENTOS_LEGALES)
                {
                    EjecutorOperacionesSP.CambiarCampoParaFiltro_Asociada_DL(properties);
                }
                #endregion
            }
            catch (Exception ex)
            {
                #region Registro de Evento Error
                LogEventos.LogArchivo log = new LogEventos.LogArchivo("LogErrores.txt");
                log.WriteEvent("--- [EVENTO] ItemUpdated ---");
                log.WriteException(ex);
                #endregion
            }
        }
        /// <summary>
        /// Eliminar un item de la lista 'Órdenes de Compra Internas'
        /// y sus items relacionados en la lista 'Ítems Pedidos'
        /// </summary>
        private void EliminarOrdenCompra()
        {
            int idOrden = Convert.ToInt32(this.IDOrdenCompra.Value);

            EjecutorOperacionesSP.EliminarOC(idOrden);
        }