Example #1
0
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            sharedMethods = new MShared();
            try
            {
                // Obtain the execution context from the service provider.
                IPluginExecutionContext     context        = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService        service        = serviceFactory.CreateOrganizationService(context.UserId);
                // The InputParameters collection contains all the data passed in the message request.

                /*Esta validación previene la ejecución del Plugin de cualquier
                 * transacción realizada a través del Web API desde Abox que usa un usuario específico*/
                if (context.InitiatingUserId == new Guid("7dbf49f3-8be8-ea11-a817-002248029f77"))
                {
                    return;
                }

                Entity         doseInput      = null;
                Entity         contact        = null;
                Entity         product        = null;
                ContactMethods contactMethods = new ContactMethods();

                UpdatePatientRequest.Request updatePatientRequest = null;

                // The InputParameters collection contains all the data passed in the message request.
                if (context.InputParameters.Contains("Target") && (context.InputParameters["Target"] is Entity) || context.InputParameters["Target"] is EntityReference)
                {
                    contactEntity = new ContactEntity();
                    doseEntity    = new DoseEntity();

                    //Cuando el plugin es un Delete, el inputParameter trae EntityReference, cuando es Create, trae Entity
                    if (context.InputParameters["Target"] is Entity)
                    {
                        /*Si existe una Preimagen, se obtiene toda la información de la entidad que se está actualizando de esta preimagen
                         * y se cambia el valor que se está actualizando*/
                        if (context.PreEntityImages.Contains("UpdatedEntity"))
                        {
                            Entity updatedDose = (Entity)context.InputParameters["Target"];
                            doseInput = (Entity)context.PreEntityImages["UpdatedEntity"];
                            if (doseInput.Attributes.Contains(DoseFields.Dose) && updatedDose.Attributes.Contains(DoseFields.Dose))
                            {
                                doseInput[DoseFields.Dose] = updatedDose[DoseFields.Dose];
                            }
                        }
                        else
                        {
                            doseInput = (Entity)context.InputParameters["Target"];
                        }
                    }
                    else if (context.InputParameters["Target"] is EntityReference && context.PreEntityImages.Contains("DeletedEntity"))
                    {
                        doseInput = (Entity)context.PreEntityImages["DeletedEntity"];
                    }

                    if (doseInput.LogicalName != doseEntity.EntitySingularName)
                    {
                        return;
                    }
                    else
                    {
                        //Cast as Entity the dose being created

                        #region -> Related Contact

                        productEntity        = new ProductEntity();
                        doseEntity           = new DoseEntity();
                        updatePatientRequest = null;

                        Guid contactId = new Guid();

                        if (doseInput.Attributes.Contains(DoseFields.ContactxDose))
                        {
                            EntityReference contactReference = (EntityReference)doseInput.Attributes[DoseFields.ContactxDose];
                            if (contactReference != null)
                            {
                                contactId = contactReference.Id;
                            }
                        }

                        string[] columnsToGet = new string[] { ContactFields.IdAboxPatient, ContactFields.Country, ContactFields.UserType, ContactFields.IdType, ContactFields.Id, ContactFields.Firstname, ContactFields.SecondLastname, ContactFields.Lastname, ContactFields.Gender, ContactFields.Birthdate };
                        var      columnSet    = new ColumnSet(columnsToGet);

                        contact = service.Retrieve(contactEntity.EntitySingularName, contactId, columnSet);

                        if (contact != null)
                        {
                            RequestHelpers helperMethods = new RequestHelpers();


                            var relatedContacts = contactMethods.GetContactChildContacts(contact, service);

                            if (relatedContacts != null)
                            {
                                if (relatedContacts.Entities.Count > 0)
                                {
                                    Exception serviceEx = new Exception("No es posible realizar esta operación en usuarios que tienen pacientes bajo cuido registrados.");
                                    serviceEx.Data["HasFeedbackMessage"] = true;
                                    throw serviceEx;
                                }
                            }

                            string userType = "";

                            if (contact.Attributes.Contains(ContactFields.UserType))
                            {
                                EntityReference userTypeReference = null;
                                userTypeReference = (EntityReference)contact.Attributes[ContactFields.UserType];
                                if (userTypeReference != null)
                                {
                                    userType = sharedMethods.GetUserTypeId(userTypeReference.Id.ToString());
                                }
                            }

                            if (userType == "05")
                            {
                                Exception serviceEx = new Exception("Es necesario cambiar el tipo de usuario de este contacto para poder gestionar los productos.");
                                serviceEx.Data["HasFeedbackMessage"] = true;
                                throw serviceEx;
                            }


                            updatePatientRequest = helperMethods.GetPatientUpdateStructure(contact, service, trace);
                        }

                        #endregion -> Related Contact

                        doseEntity = new DoseEntity();
                        switch (context.MessageName.ToLower())
                        {
                        case "create":

                            #region Dose Created

                            //Validar que exista la relación Dosis-Producto
                            if (doseInput.Attributes.Contains(DoseFields.DosexProduct))
                            {
                                EntityReference productReference = null;
                                //Se obtiene la referencia del producto que tiene la entidad Dosis
                                productReference = (EntityReference)doseInput.Attributes[DoseFields.DosexProduct];
                                if (productReference != null)
                                {
                                    //Se obtiene el producto
                                    product = service.Retrieve(productEntity.EntitySingularName, productReference.Id, new ColumnSet(new string[] { ProductFields.ProductNumber }));

                                    //Se obtiene el ID del producto
                                    if (product.Attributes.Contains(ProductFields.ProductNumber))
                                    {
                                        string frequency = "";

                                        if (doseInput.Attributes.Contains(DoseFields.Dose))
                                        {
                                            int value = (doseInput.GetAttributeValue <OptionSetValue>(DoseFields.Dose)).Value;
                                            frequency = sharedMethods.GetDoseFrequencyValue(value);
                                        }

                                        if (updatePatientRequest.medication == null)
                                        {
                                            updatePatientRequest.medication = new UpdatePatientRequest.Request.Medication();
                                        }

                                        if (updatePatientRequest.medication.products != null)
                                        {
                                            //guardar la cantidad de productos que tiene el paciente
                                            var tempProducts = updatePatientRequest.medication.products;

                                            //inicializar un nuevo array con una posición adicional que guardará el nuevo dosis-producto
                                            updatePatientRequest.medication.products = new UpdatePatientRequest.Request.Product[tempProducts.Length + 1];

                                            for (int i = 0; i < tempProducts.Length; i++)
                                            {
                                                updatePatientRequest.medication.products[i] = new UpdatePatientRequest.Request.Product
                                                {
                                                    frequency = tempProducts[i].frequency,
                                                    productid = tempProducts[i].productid
                                                };
                                            }

                                            //agregar el nuevo dosis-producto al array
                                            updatePatientRequest.medication.products[updatePatientRequest.medication.products.Length - 1] = new UpdatePatientRequest.Request.Product
                                            {
                                                frequency = frequency,
                                                productid = product.GetAttributeValue <string>(ProductFields.ProductNumber)
                                            };
                                        }
                                        else
                                        {
                                            updatePatientRequest.medication.products = new UpdatePatientRequest.Request.Product[1];
                                            updatePatientRequest.medication.products[updatePatientRequest.medication.products.Length - 1] = new UpdatePatientRequest.Request.Product
                                            {
                                                frequency = frequency,
                                                productid = product.GetAttributeValue <string>(ProductFields.ProductNumber)
                                            };
                                        }
                                    }
                                }
                            }

                            #endregion Dose Created

                            break;

                        case "delete":

                            //Validar que exista la relación Dosis-Producto
                            if (doseInput.Attributes.Contains(DoseFields.EntityId))
                            {
                                EntityReference productReference = null;
                                productReference = (EntityReference)doseInput.Attributes[DoseFields.DosexProduct];

                                //Se obtiene la referencia del producto que tiene la entidad Dosis
                                product = service.Retrieve(productEntity.EntitySingularName, productReference.Id, new ColumnSet(new string[] { ProductFields.ProductNumber }));

                                if (product != null)
                                {
                                    //Se obtiene el ID del producto
                                    if (product.Attributes.Contains(ProductFields.ProductNumber))
                                    {
                                        if (updatePatientRequest.medication != null)
                                        {
                                            System.Collections.Generic.List <UpdatePatientRequest.Request.Product> productsToSave = new System.Collections.Generic.List <UpdatePatientRequest.Request.Product>();

                                            for (int i = 0; i < updatePatientRequest.medication.products.Length; i++)
                                            {
                                                /*Agregar a la lista de los productos-dosis que se enviarán al servicio todos los productos excepto el producto de la dosis que se está eliminando*/
                                                if (updatePatientRequest.medication.products[i].productid != product.GetAttributeValue <string>(ProductFields.ProductNumber))
                                                {
                                                    productsToSave.Add(updatePatientRequest.medication.products[i]);
                                                }
                                            }

                                            int countProductsRelated = updatePatientRequest.medication.products.Length;

                                            //reducir el tamaño del array
                                            updatePatientRequest.medication.products = new UpdatePatientRequest.Request.Product[countProductsRelated - 1];

                                            //agregar los productos que se van a guardar.
                                            for (int i = 0; i < updatePatientRequest.medication.products.Length; i++)
                                            {
                                                updatePatientRequest.medication.products[i] = productsToSave[i];
                                            }
                                        }
                                    }
                                }
                            }

                            break;

                        case "update":

                            //Validar que exista la relación Dosis-Producto
                            if (doseInput.Attributes.Contains(DoseFields.DosexProduct))
                            {
                                EntityReference productReference = null;
                                //Se obtiene la referencia del producto que tiene la entidad Dosis
                                productReference = (EntityReference)doseInput.Attributes[DoseFields.DosexProduct];
                                if (productReference != null)
                                {
                                    //Se obtiene el producto
                                    product = service.Retrieve(productEntity.EntitySingularName, productReference.Id, new ColumnSet(new string[] { ProductFields.ProductNumber }));

                                    //Se obtiene el ID del producto
                                    if (product.Attributes.Contains(ProductFields.ProductNumber))
                                    {
                                        string frequency = "";

                                        if (doseInput.Attributes.Contains(DoseFields.Dose))
                                        {
                                            int value = (doseInput.GetAttributeValue <OptionSetValue>(DoseFields.Dose)).Value;
                                            frequency = sharedMethods.GetDoseFrequencyValue(value);
                                        }

                                        if (updatePatientRequest.medication == null)
                                        {
                                            updatePatientRequest.medication = new UpdatePatientRequest.Request.Medication();
                                        }

                                        for (int i = 0; i < updatePatientRequest.medication.products.Length; i++)
                                        {
                                            //Buscar el producto que se está actualizando para cambiarle los datos
                                            if (updatePatientRequest.medication.products[i].productid == product.GetAttributeValue <string>(ProductFields.ProductNumber))
                                            {
                                                //actualizar la frecuencia, el producto no debe actualizarse, para esto se crea otro
                                                updatePatientRequest.medication.products[i] = new UpdatePatientRequest.Request.Product
                                                {
                                                    frequency = frequency,
                                                    productid = updatePatientRequest.medication.products[i].productid
                                                };
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            break;
                        }

                        ///Request service POST
                        ///

                        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.Request));
                        MemoryStream memoryStream             = new MemoryStream();
                        serializer.WriteObject(memoryStream, updatePatientRequest);
                        var jsonObject = Encoding.Default.GetString(memoryStream.ToArray());
                        memoryStream.Dispose();

                        //Valores necesarios para hacer el Post Request
                        WebRequestData wrData = new WebRequestData();
                        wrData.InputData     = jsonObject;
                        wrData.ContentType   = "application/json";
                        wrData.Authorization = "Bearer " + Configuration.TokenForAboxServices;

                        wrData.Url = AboxServices.UpdatePatientService;

                        var serviceResponse = sharedMethods.DoPostRequest(wrData, trace);
                        UpdatePatientRequest.ServiceResponse serviceResponseProperties = null;
                        if (serviceResponse.IsSuccessful)
                        {
                            DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.ServiceResponse));

                            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(serviceResponse.Data)))
                            {
                                deserializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.ServiceResponse));
                                serviceResponseProperties = (UpdatePatientRequest.ServiceResponse)deserializer.ReadObject(ms);
                            }

                            if (serviceResponseProperties.response.code != "MEMCTRL-1014")
                            {
                                trace.Trace(Constants.ErrorMessageCodeReturned + serviceResponseProperties.response.code);

                                Exception serviceEx = new Exception(Constants.GeneralAboxServicesErrorMessage + serviceResponseProperties.response.message);
                                serviceEx.Data["HasFeedbackMessage"] = true;
                                throw serviceEx;
                            }
                            else
                            {
                                //contact.Attributes.Add("new_idaboxpatient", serviceResponseProperties.response.details.idPaciente);
                            }
                        }
                        else
                        {
                            throw new InvalidPluginExecutionException(Constants.GeneralAboxServicesErrorMessage);
                        }

                        //TODO: Capturar excepción con servicios de Abox Plan y hacer un Logging
                    }
                }
            }
            catch (Exception ex)
            {
                trace.Trace($"MethodName: {new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name}|--|Exception: " + ex.ToString());

                try
                {
                    sharedMethods.LogPluginFeedback(new LogClass
                    {
                        Exception  = ex.ToString(),
                        Level      = "error",
                        ClassName  = this.GetType().ToString(),
                        MethodName = System.Reflection.MethodBase.GetCurrentMethod().Name,
                        Message    = "Excepción en plugin",
                        ProcessId  = ""
                    }, trace);
                }
                catch (Exception e)
                {
                    trace.Trace($"MethodName: {new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name}|--|Exception: " + e.ToString());
                }

                if (ex.Data["HasFeedbackMessage"] != null)
                {
                    throw new InvalidPluginExecutionException(ex.Message);
                }
                else
                {
                    throw new InvalidPluginExecutionException(Constants.GeneralPluginErrorMessage);
                }
            }
        }
Example #2
0
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            sharedMethods = new MShared();
            try
            {
                IPluginExecutionContext     context        = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService        service        = serviceFactory.CreateOrganizationService(context.UserId);

                /*Esta validación previene la ejecución del Plugin de cualquier
                 * transacción realizada a través del Web API desde Abox*/
                if (context.InitiatingUserId == new Guid("7dbf49f3-8be8-ea11-a817-002248029f77"))
                {
                    return;
                }

                Entity contactUpdated = null;
                UpdatePatientRequest.Request     updatePatientRequest = null;
                UpdateAccountRequest.Request     updateAccountRequest = null;
                SignupIntoAccountRequest.Request patientSignupRequest = null;
                ContactMethods contactMethods = new ContactMethods();

                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    contactEntity  = new ContactEntity();
                    contactUpdated = (Entity)context.InputParameters["Target"];
                    if (contactUpdated.LogicalName != contactEntity.EntitySingularName)
                    {
                        return;
                    }
                    else
                    {
                        if (contactUpdated != null)
                        {
                            /*Desde otros plugins, cuando se cambia un valor de un field a nivel de código o se crea una realcion,
                             * automáticamente llama la ejecución de este plugin. Esta validación se hace porque desde el plugin de ChildContactsAssociation,
                             *  luego de realizar el registro de tutor y el hijo en la BD mediante los servicios, se hace una asociación en Dynamics,
                             * y por lo tanto este plugin se ejecuta para actualizar el valor del lookup del contacto hijo referenciando al contacto padre*/
                            if (contactUpdated.Attributes.Keys.Contains(ContactFields.ContactxContactLookup))
                            {
                                return;
                            }

                            if (contactUpdated.Attributes.Keys.Contains(ContactFields.IdAboxPatient))
                            {
                                return;
                            }

                            helperMethods = new RequestHelpers();

                            #region -> Set request data based on Contact

                            //contactMethods = new ContactMethods();

                            string[] columnsToGet = new string[] { ContactFields.IdAboxPatient, ContactFields.Country, ContactFields.Province, ContactFields.Canton, ContactFields.District, ContactFields.Interests, ContactFields.UserType, ContactFields.IdType, ContactFields.Id, ContactFields.Firstname, ContactFields.SecondLastname, ContactFields.Lastname, ContactFields.Gender, ContactFields.Birthdate, ContactFields.ContactxContactLookup, ContactFields.Phone, ContactFields.SecondaryPhone, ContactFields.Email, ContactFields.IsChildContact, ContactFields.NoEmail, ContactFields.IsUserTypeChange };
                            var      columnSet    = new ColumnSet(columnsToGet);
                            Entity   contactData  = service.Retrieve(contactEntity.EntitySingularName, contactUpdated.Id, columnSet);

                            //Limitar ejecucion del Plugin cuando el ID ABOX PATIENT de Dynamics está vacío.
                            if (!contactData.Attributes.Contains(ContactFields.IdAboxPatient))
                            {
                                Exception ex = new Exception($"Este contacto no posee un ID de paciente Abox registrado. Por favor contacte al administrador.");
                                ex.Data["HasFeedbackMessage"] = true;
                                throw ex;
                            }

                            string userType = "";

                            if (contactData.Attributes.Contains(ContactFields.UserType))
                            {
                                EntityReference userTypeReference = null;
                                userTypeReference = (EntityReference)contactData.Attributes[ContactFields.UserType];
                                if (userTypeReference != null)
                                {
                                    userType = sharedMethods.GetUserTypeId(userTypeReference.Id.ToString());
                                }
                            }

                            /*Recorrer los atributos que cambiaron y sobreescribirselos a la entidad contacto actual para
                             * tener la información completa que se enviará al servicio*/
                            foreach (string keyName in contactUpdated.Attributes.Keys)
                            {
                                if (contactData.Attributes.ContainsKey(keyName))
                                {
                                    contactData.Attributes[keyName] = contactUpdated.Attributes[keyName];
                                }
                            }


                            //Validar Datos

                            var validationStatusMessages = contactMethods.GetEntityValidationStatus(contactData, trace);

                            if (validationStatusMessages.Count > 0)
                            {
                                string messageRows = "";


                                //foreach (var message in validationStatusMessages)
                                //{
                                //    messageRows += message+"\n";
                                //}

                                /*El mensaje que se envia al usuario a Dynamics es poco amigable y si se envia un mensaje muy largo, la forma en que lo muestra es completamente
                                 * ilegible, por esto solo se muestra un mensaje a la vez
                                 * Para mostrar un mensaje mas amigable, hay que implementar un propio boton de Save en el Ribbon*/
                                messageRows = validationStatusMessages[0];
                                Exception ex = new Exception($"{messageRows}");
                                ex.Data["HasFeedbackMessage"] = true;
                                throw ex;
                            }

                            bool isProfileChange = false;

                            if (contactData.Attributes.Contains(ContactFields.IsUserTypeChange))
                            {
                                isProfileChange = contactData.GetAttributeValue <bool>(ContactFields.IsUserTypeChange);
                            }

                            EntityReference newUserTypeReference = null;
                            //TODO: Usar algun field para indicar que el usuario esta explicitamente haciendo un cambio de perfil
                            if (isProfileChange && contactData.Attributes.Contains(ContactFields.UserType))
                            {
                                patientSignupRequest = helperMethods.GetSignupPatientIntoAccountRequestObject(contactData, service, trace);
                                newUserTypeReference = (EntityReference)contactData.Attributes[ContactFields.UserType];
                            }

                            /*Validar si es un usuario tipo Paciente y no tiene un cuidador o tutor, se utilizara el servicio
                             * de update patient*/
                            else if (contactData.Attributes.Contains(ContactFields.ContactxContactLookup))
                            {
                                updatePatientRequest = helperMethods.GetPatientUpdateStructure(contactData, service, trace);
                            }
                            else
                            {
                                //Si es cuidador, tutor, o paciente que no está a cargo de nadie se usa el update account
                                updateAccountRequest = helperMethods.GetAccountUpdateStructure(contactData, service, trace);
                            }


                            //else
                            //{
                            //    string contactName = "";

                            //    if (contactData.Attributes.Contains(ContactFields.Firstname))
                            //        contactName += contactData.GetAttributeValue<string>(ContactFields.Firstname);

                            //    if (contactData.Attributes.Contains(ContactFields.Lastname))
                            //        contactName += " " + contactData.GetAttributeValue<string>(ContactFields.Lastname);

                            //    if (contactData.Attributes.Contains(ContactFields.SecondLastname))
                            //        contactName += " " + contactData.GetAttributeValue<string>(ContactFields.SecondLastname);

                            //    Exception ex = new Exception($"Ocurrió un problema identificando el tipo de usuario del contacto. {(!String.IsNullOrEmpty(contactName) ? "(" + contactName + ")" : "")}");
                            //    ex.Data["HasFeedbackMessage"] = true;
                            //    throw ex;
                            //}

                            #endregion -> Set request data based on Contact

                            DataContractJsonSerializer serializer = null;
                            MemoryStream memoryStream             = new MemoryStream();
                            string       serviceUrl = "";

                            if (isProfileChange)
                            {
                                serializer = new DataContractJsonSerializer(typeof(SignupIntoAccountRequest.Request));
                                serializer.WriteObject(memoryStream, patientSignupRequest);
                                serviceUrl = AboxServices.SignIntoAccountService;
                            }
                            else
                            {
                                if (updatePatientRequest != null)
                                {
                                    serializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.Request));
                                    serializer.WriteObject(memoryStream, updatePatientRequest);
                                    serviceUrl = AboxServices.UpdatePatientService;
                                }
                                else if (updateAccountRequest != null)
                                {
                                    serializer = new DataContractJsonSerializer(typeof(UpdateAccountRequest.Request));
                                    serializer.WriteObject(memoryStream, updateAccountRequest);
                                    serviceUrl = AboxServices.UpdateAccountService;
                                }
                            }



                            var jsonObject = Encoding.Default.GetString(memoryStream.ToArray());
                            memoryStream.Dispose();

                            //Valores necesarios para hacer el Post Request
                            WebRequestData wrData = new WebRequestData();
                            wrData.InputData     = jsonObject;
                            wrData.ContentType   = "application/json";
                            wrData.Authorization = "Bearer " + Configuration.TokenForAboxServices;

                            wrData.Url = serviceUrl;

                            var serviceResponse = sharedMethods.DoPostRequest(wrData, trace);
                            UpdatePatientRequest.ServiceResponse     updatePatientResponse   = null;
                            UpdateAccountRequest.ServiceResponse     updateAccountResponse   = null;
                            SignupIntoAccountRequest.ServiceResponse signIntoAccountResponse = null;
                            if (serviceResponse.IsSuccessful)
                            {
                                if (isProfileChange && patientSignupRequest != null)
                                {
                                    //

                                    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(SignupIntoAccountRequest.ServiceResponse));

                                    using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(serviceResponse.Data)))
                                    {
                                        deserializer            = new DataContractJsonSerializer(typeof(SignupIntoAccountRequest.ServiceResponse));
                                        signIntoAccountResponse = (SignupIntoAccountRequest.ServiceResponse)deserializer.ReadObject(ms);
                                    }

                                    if (signIntoAccountResponse.response.code.ToString() != "0")
                                    {
                                        trace.Trace(Constants.ErrorMessageCodeReturned + signIntoAccountResponse.response.code);

                                        Exception serviceEx = new Exception(Constants.GeneralAboxServicesErrorMessage + signIntoAccountResponse.response.message);
                                        serviceEx.Data["HasFeedbackMessage"] = true;
                                        throw serviceEx;
                                    }
                                    else
                                    {
                                        //contact.Attributes.Add("new_idaboxpatient", serviceResponseProperties.response.details.idPaciente);
                                        if (isProfileChange && newUserTypeReference != null)
                                        {
                                            if (contactData.Attributes.Contains(ContactFields.UserType))
                                            {
                                                contactData.Attributes.Remove(ContactFields.UserType);
                                                contactData.Attributes.Add(ContactFields.UserType, newUserTypeReference);
                                            }
                                            else
                                            {
                                                contactData.Attributes.Add(ContactFields.UserType, newUserTypeReference);
                                            }
                                        }
                                    }

                                    //
                                }
                                else if (updatePatientRequest != null)
                                {
                                    //Leer respuesta del servicio de Update Patient

                                    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.ServiceResponse));

                                    using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(serviceResponse.Data)))
                                    {
                                        deserializer          = new DataContractJsonSerializer(typeof(UpdatePatientRequest.ServiceResponse));
                                        updatePatientResponse = (UpdatePatientRequest.ServiceResponse)deserializer.ReadObject(ms);
                                    }

                                    if (updatePatientResponse.response.code != "MEMCTRL-1014")
                                    {
                                        Exception serviceEx = new Exception(Constants.GeneralAboxServicesErrorMessage + updatePatientResponse.response.message);
                                        serviceEx.Data["HasFeedbackMessage"] = true;
                                        throw serviceEx;
                                    }
                                    else
                                    {
                                    }
                                }
                                else if (updateAccountRequest != null)
                                {
                                    //Leer respuesta del servicio Update Account
                                    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UpdateAccountRequest.ServiceResponse));

                                    using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(serviceResponse.Data)))
                                    {
                                        deserializer          = new DataContractJsonSerializer(typeof(UpdateAccountRequest.ServiceResponse));
                                        updateAccountResponse = (UpdateAccountRequest.ServiceResponse)deserializer.ReadObject(ms);
                                    }

                                    if (updateAccountResponse.response.code != "MEMCTRL-1015")
                                    {
                                        trace.Trace(Constants.ErrorMessageCodeReturned + updateAccountResponse.response.code);
                                        throw new InvalidPluginExecutionException(Constants.ErrorMessageTransactionCodeReturned + updateAccountResponse.response.message);
                                    }
                                    else
                                    {
                                        //contact.Attributes.Add("new_idaboxpatient", serviceResponseProperties.response.details.idPaciente);
                                    }
                                }
                            }
                            else
                            {
                                Exception ex = new Exception(Constants.GeneralAboxServicesErrorMessage);
                                ex.Data["HasFeedbackMessage"] = true;
                                throw ex;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                trace.Trace($"MethodName: {new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name}|--|Exception: " + ex.ToString());

                try
                {
                    sharedMethods.LogPluginFeedback(new LogClass
                    {
                        Exception  = ex.ToString(),
                        Level      = "error",
                        ClassName  = this.GetType().ToString(),
                        MethodName = System.Reflection.MethodBase.GetCurrentMethod().Name,
                        Message    = "Excepción en plugin",
                        ProcessId  = ""
                    }, trace);
                }
                catch (Exception e)
                {
                    trace.Trace($"MethodName: {new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name}|--|Exception: " + e.ToString());
                }

                if (ex.Data["HasFeedbackMessage"] != null)
                {
                    throw new InvalidPluginExecutionException(ex.Message);
                }
                else
                {
                    throw new InvalidPluginExecutionException(Constants.GeneralPluginErrorMessage);
                }
            }
        }
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            sharedMethods = new MShared();
            try
            {
                // Obtain the execution context from the service provider.
                IPluginExecutionContext     context        = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService        service        = serviceFactory.CreateOrganizationService(context.UserId);
                // The InputParameters collection contains all the data passed in the message request.

                /*Esta validación previene la ejecución del Plugin de cualquier
                 * transacción realizada a través del Web API desde Abox*/
                if (context.InitiatingUserId == new Guid("7dbf49f3-8be8-ea11-a817-002248029f77"))
                {
                    return;
                }

                EntityReference targetEntity = null;

                string relationshipName = string.Empty;

                EntityReferenceCollection relatedEntities = null;

                EntityReference doctorRelated = null;

                Entity contact = null;

                UpdatePatientRequest.Request updatePatientRequest = null;

                #region Associate & Disassociate

                // if (context.MessageName.ToLower() == "associate" || context.MessageName.ToLower() == "disassociate")
                if (context.MessageName.ToLower() == "associate" || context.MessageName.ToLower() == "disassociate")
                {
                    contactEntity = new ContactEntity();

                    // Get the “Relationship” Key from context

                    if (context.InputParameters.Contains("Relationship"))

                    {
                        // Get the Relationship name for which this plugin fired
                        relationshipName = ((Relationship)context.InputParameters["Relationship"]).SchemaName;
                    }

                    // Check the "Relationship Name" with your intended one

                    if (relationshipName != ContactFields.ContactxDoctorRelationship)
                    {
                        return;
                    }
                    else
                    {
                        productEntity        = new ProductEntity();
                        updatePatientRequest = new UpdatePatientRequest.Request();
                        ContactMethods contactMethods = new ContactMethods();
                        #region -> Target

                        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
                        {
                            helperMethods = new RequestHelpers();
                            targetEntity  = (EntityReference)context.InputParameters["Target"];

                            string[] columnsToGet = new string[] { ContactFields.IdAboxPatient, ContactFields.Country, ContactFields.UserType, ContactFields.IdType, ContactFields.Id, ContactFields.Firstname, ContactFields.SecondLastname, ContactFields.Lastname, ContactFields.Gender, ContactFields.Birthdate };
                            var      columnSet    = new ColumnSet(columnsToGet);
                            contact = service.Retrieve(contactEntity.EntitySingularName, targetEntity.Id, columnSet);

                            var relatedContacts = contactMethods.GetContactChildContacts(contact, service);

                            if (relatedContacts != null)
                            {
                                if (relatedContacts.Entities.Count > 0)
                                {
                                    Exception serviceEx = new Exception("No es posible realizar esta operación en usuarios que tienen pacientes bajo cuido registrados.");
                                    serviceEx.Data["HasFeedbackMessage"] = true;
                                    throw serviceEx;
                                }
                            }


                            string userType = "";

                            if (contact.Attributes.Contains(ContactFields.UserType))
                            {
                                EntityReference userTypeReference = null;
                                userTypeReference = (EntityReference)contact.Attributes[ContactFields.UserType];
                                if (userTypeReference != null)
                                {
                                    userType = sharedMethods.GetUserTypeId(userTypeReference.Id.ToString());
                                }
                            }

                            if (userType == "05")
                            {
                                Exception serviceEx = new Exception("Es necesario cambiar el tipo de usuario de este contacto para poder agregar médicos.");
                                serviceEx.Data["HasFeedbackMessage"] = true;
                                throw serviceEx;
                            }
                            //updatePatientRequest.personalinfo = new UpdatePatientRequest.Request.Personalinfo();



                            updatePatientRequest = helperMethods.GetPatientUpdateStructure(contact, service, trace);
                        }

                        #endregion -> Target

                        #region -> Related

                        doctorEntity    = new DoctorEntity();
                        relatedEntities = context.InputParameters["RelatedEntities"] as EntityReferenceCollection;

                        if (relatedEntities.Count > 0)
                        {
                            if (context.MessageName.ToLower() == "associate")
                            {
                                #region -> Associate

                                int relatedEntitiesCount         = relatedEntities.Count;
                                int contactCurrentRelatedDoctors = 0;
                                System.Collections.Generic.List <UpdatePatientRequest.Request.Medic> medicsToSave = new System.Collections.Generic.List <UpdatePatientRequest.Request.Medic>();
                                if (updatePatientRequest.medication == null)
                                {
                                    updatePatientRequest.medication        = new UpdatePatientRequest.Request.Medication();
                                    updatePatientRequest.medication.medics = new UpdatePatientRequest.Request.Medic[relatedEntitiesCount];
                                }
                                else
                                {
                                    if (updatePatientRequest.medication.medics == null)
                                    {
                                        updatePatientRequest.medication.medics = new UpdatePatientRequest.Request.Medic[relatedEntitiesCount];
                                    }
                                    else
                                    {
                                        contactCurrentRelatedDoctors = updatePatientRequest.medication.medics.Length;

                                        if (contactCurrentRelatedDoctors > 0)
                                        {
                                            for (int i = 0; i < contactCurrentRelatedDoctors; i++)
                                            {
                                                medicsToSave.Add(updatePatientRequest.medication.medics[i]);
                                            }

                                            updatePatientRequest.medication.medics = new UpdatePatientRequest.Request.Medic[relatedEntitiesCount + contactCurrentRelatedDoctors];
                                        }
                                    }
                                }

                                for (int i = 0; i < relatedEntitiesCount; i++)
                                {
                                    doctorRelated = relatedEntities[i];

                                    Entity doctor = service.Retrieve(doctorEntity.EntitySingularName, doctorRelated.Id, new ColumnSet(DoctorFields.DoctorIdKey));
                                    if (doctor.Attributes.Contains(DoctorFields.DoctorIdKey))
                                    {
                                        medicsToSave.Add(new UpdatePatientRequest.Request.Medic
                                        {
                                            medicid = doctor.GetAttributeValue <string>(DoctorFields.DoctorIdKey)
                                        });
                                    }
                                }

                                int totalMedicsToSaveCount = updatePatientRequest.medication.medics.Length;
                                for (int i = 0; i < totalMedicsToSaveCount; i++)
                                {
                                    updatePatientRequest.medication.medics[i] = medicsToSave[i];
                                }

                                #endregion -> Associate
                            }
                            else
                            {
                                #region -> Disassociate

                                if (updatePatientRequest.medication != null)
                                {
                                    if (updatePatientRequest.medication.medics != null)
                                    {
                                        System.Collections.Generic.List <UpdatePatientRequest.Request.Medic> medicsToSave = new System.Collections.Generic.List <UpdatePatientRequest.Request.Medic>();

                                        //Recorrer la lista de medicos que se estan desasociando del contacto
                                        foreach (var relatedItem in relatedEntities)
                                        {
                                            //Obtener la entidad con el Id de Medico
                                            Entity doctorToRemove = service.Retrieve(doctorEntity.EntitySingularName, relatedItem.Id, new ColumnSet(DoctorFields.DoctorIdKey));
                                            int    medicsLength   = updatePatientRequest.medication.medics.Length;

                                            //Buscar en la lista de medicos que tiene el usuario
                                            for (int i = 0; i < medicsLength; i++)
                                            {
                                                //Agregar a la lista de medicos a guardar, aquellos que no fueron desasociados
                                                if (updatePatientRequest.medication.medics[i].medicid != doctorToRemove.GetAttributeValue <string>(DoctorFields.DoctorIdKey))
                                                {
                                                    medicsToSave.Add(updatePatientRequest.medication.medics[i]);
                                                }
                                            }
                                        }

                                        //Enviar como null si no hay pacientes a guardar
                                        if (medicsToSave.Count == 0)
                                        {
                                            updatePatientRequest.medication.medics = null;
                                        }
                                        else
                                        {
                                            //Modificar el tamaño del array y agregar los médicos que se guardarán
                                            updatePatientRequest.medication.medics = new UpdatePatientRequest.Request.Medic[medicsToSave.Count];
                                            int length = updatePatientRequest.medication.medics.Length;
                                            for (int i = 0; i < length; i++)
                                            {
                                                updatePatientRequest.medication.medics[i] = medicsToSave[i];
                                            }
                                        }
                                    }
                                }

                                #endregion -> Disassociate
                            }
                        }

                        #endregion -> Related

                        ///Request service POST
                        ///

                        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.Request));
                        MemoryStream memoryStream             = new MemoryStream();
                        serializer.WriteObject(memoryStream, updatePatientRequest);
                        var jsonObject = Encoding.Default.GetString(memoryStream.ToArray());
                        memoryStream.Dispose();

                        //Valores necesarios para hacer el Post Request
                        WebRequestData wrData = new WebRequestData();
                        wrData.InputData     = jsonObject;
                        wrData.ContentType   = "application/json";
                        wrData.Authorization = "Bearer " + Configuration.TokenForAboxServices;

                        wrData.Url = AboxServices.UpdatePatientService;

                        var serviceResponse = sharedMethods.DoPostRequest(wrData, trace);
                        UpdatePatientRequest.ServiceResponse serviceResponseProperties = null;
                        if (serviceResponse.IsSuccessful)
                        {
                            DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.ServiceResponse));

                            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(serviceResponse.Data)))
                            {
                                deserializer = new DataContractJsonSerializer(typeof(UpdatePatientRequest.ServiceResponse));
                                serviceResponseProperties = (UpdatePatientRequest.ServiceResponse)deserializer.ReadObject(ms);
                            }

                            if (serviceResponseProperties.response.code != "MEMCTRL-1014")
                            {
                                trace.Trace(Constants.ErrorMessageCodeReturned + serviceResponseProperties.response.code);

                                Exception serviceEx = new Exception(Constants.GeneralAboxServicesErrorMessage + serviceResponseProperties.response.message);
                                serviceEx.Data["HasFeedbackMessage"] = true;
                                throw serviceEx;
                            }
                            else
                            {
                                //contact.Attributes.Add("new_idaboxpatient", serviceResponseProperties.response.details.idPaciente);
                            }
                        }
                        else
                        {
                            throw new InvalidPluginExecutionException(Constants.GeneralAboxServicesErrorMessage);
                        }
                    }
                }

                #endregion Associate & Disassociate
            }
            catch (Exception ex)
            {
                trace.Trace($"MethodName: {new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name}|--|Exception: " + ex.ToString());

                try
                {
                    sharedMethods.LogPluginFeedback(new LogClass
                    {
                        Exception  = ex.ToString(),
                        Level      = "error",
                        ClassName  = this.GetType().ToString(),
                        MethodName = System.Reflection.MethodBase.GetCurrentMethod().Name,
                        Message    = "Excepción en plugin",
                        ProcessId  = ""
                    }, trace);
                }
                catch (Exception e)
                {
                    trace.Trace($"MethodName: {new System.Diagnostics.StackTrace(ex).GetFrame(0).GetMethod().Name}|--|Exception: " + e.ToString());
                }

                if (ex.Data["HasFeedbackMessage"] != null)
                {
                    throw new InvalidPluginExecutionException(ex.Message);
                }
                else
                {
                    throw new InvalidPluginExecutionException(Constants.GeneralPluginErrorMessage);
                }
            }
        }