//En fonction de l'attribution du message dans la tâche et du rôle du user => il voit le message ou pas
        private static bool CanSeeMessage(ClConversation elem, TaskUser user, ServiceGateWayClient gatewayITask)
        {
            var recipientsTaskUser = new List <string>();

            if (elem.Confidential == 1)
            {
                var listrec = gatewayITask.GetAllTaskUser(false);
                //récupération des personnes qui ont reçu le message
                foreach (var rec in elem.Recipient)
                {
                    var elt = listrec.FirstOrDefault(a => a.HrIdTechnique.ToString() == rec);
                    if (elt != null)
                    {
                        recipientsTaskUser.Add(elt.HrIdTechnique.ToString());
                    }
                }
            }
            //remove draft messages from others
            if (elem.ContributionType == 8 && elem.AuthorAgent.HrIdTechnique.ToString() != user.Id)
            {
                return(false);
            }

            if ((elem.Confidential == 0) || (elem.Confidential == 1 && (elem.AuthorAgent.HrIdTechnique.ToString() == user.Id || recipientsTaskUser.Contains(user.Id))))
            {
                return(true);
            }
            return(false);
        }
        private static async Task <bool> SaveComment(ServiceGateWayClient gatewayITask, TaskUser user, ClTaskDocument taskDocument, List <ClJoinFile> files, SendMessageViewModel model)
        {
            var clcomment = new ClComment
            {
                CurrentTask       = new ClTaskDocument(),
                joinFiles         = files.ToArray(),
                Confidential      = model.IsConfidential ? 1 : 0,
                TaskStatus        = model.Status,
                MailBodyIsHtml    = true,
                MailBody          = model.Message,
                AuthorMailComment = user.Email
            };

            Log.Write("SaveComment", "Conversation", model.TaskId.ToString(), 3, "debut AddComment");
            var ret = await Task.Run(() => gatewayITask.AddComment(taskDocument, clcomment, user.Id, "CONVERSATION"));

            Log.Write("SaveComment", "Conversation", model.TaskId.ToString(), 3, "fin AddComment");
            return(ret);
        }
        private static async Task <bool> SaveInternMessage(ServiceGateWayClient gatewayITask, TaskUser user, ClTaskDocument taskDocument, List <ClJoinFile> files, SendMessageViewModel model)
        {
            var internalMail = new ClInternConversation
            {
                TaskStatus     = model.Status,
                Subject        = model.DefaultSubject + " " + model.CustomSubject ?? "",
                MailBody       = model.Message,
                From           = user.Email,
                Confidential   = model.IsConfidential ? 1 : 0,
                CopyCc         = FormatStringToArray(model.StringCopyToId),
                joinFiles      = files.ToArray(),
                MailBodyIsHtml = true,
                Recipient      = model.InternRecipientId
            };

            // RM 120977 - Message interne sans attribution: Erreur message de notification
            internalMail.AttributeTask = model.AssignToUser;

            return(await Task.Run(() => gatewayITask.AddInternConversation(taskDocument, internalMail, user.Id, false)));
        }
        private static async Task <ResultViewModel> SaveExternMessage(ServiceGateWayClient gatewayITask, TaskUser user, ClTaskDocument taskDocument, List <ClJoinFile> files, Dictionary <string, byte[]> filesForEmail, SendMessageViewModel model)
        {
            //Mail destiné à l'extérieur

            bool result         = true;
            long employerNumber = model.EmployerNumber;
            long workerNumber   = model.WorkerNumber;

            if (model.IsNewTask)
            {
                //change status to new when creating new task from draft
                if (model.TypeOfMessage == 8)
                {
                    model.Status = 1;
                }

                //création de la tâche avant de créer l'élément de conversation si c'est un email direct
                long taskId  = 0;
                var  taskNew = new TaskDocumentViewModel
                {
                    Task = new TaskViewModel
                    {
                        FormattedBeginDate = DateTime.MinValue.ToString("dd-MM-yyyy"),
                        Description        = model.CustomSubject,
                        TechnicalId        = model.TaskId,
                        Type            = 5, //par défaut - traitement d'email
                        Priority        = 2,
                        ExpectedEndDate = DateTime.Now,
                        BeginDate       = DateTime.MinValue,
                        EmployerNumber  = employerNumber,
                        WorkerNumber    = workerNumber
                    },
                    Affectation = new AffectationViewModel
                    {
                        SelectedAgent  = user.Id,
                        SelectedEntity = user.CurrentEntityIdTechnique.ToString()
                    },
                    Context        = user.CurrentContext,
                    OrigineContext = user.CurrentOriginContext,
                    CurrentStatus  = model.Status,
                };

                var mailTo = FormatStringToArrayWithoutDot(model.InternRecipient);
                // Si un seul employeur dans le To -> récupérer son n° d'employeur
                if (mailTo.Count() == 1 && employerNumber == 0)
                {
                    employerNumber = gatewayITask.GetEmployerFromEmail(mailTo[0]);
                    taskNew.Task.EmployerNumber = employerNumber;
                }

                // Mise à jour date début si nécessaire
                if (model.Status == 2)
                {
                    taskNew.Task.BeginDate          = DateTime.Now;
                    taskNew.Task.FormattedBeginDate = DateTime.Now.ToString("dd-MM-yyyy");
                }
                // Mise à jour date fin si nécessaire
                if (model.Status == 4)
                {
                    if (employerNumber > 0)
                    {
                        taskNew.Task.EffectiveEndDate          = DateTime.Now;
                        taskNew.Task.FormattedEffectiveEndDate = DateTime.Now.ToString("dd-MM-yyyy");
                    }
                    else
                    {
                        //changing to new when there is no employer
                        model.Status          = 1;
                        taskNew.CurrentStatus = 1;
                    }
                }

                result = await Task.Run(() => gatewayITask.InsertTaskDocument(MapClTaskDocumentToTaskDocumentViewModel.Map(taskNew), user.Id, ref taskId, user.CurrentEntityNumber));
            }

            var externMail = new ClExternMail
            {
                Subject  = model.DefaultSubject + " " + model.CustomSubject ?? "",
                MailBody = model.Message,
                Draft    = model.TypeOfMessage == 8,
                //MailBodyText = "je stocke du texte" + model.Message,
                From           = user.Email,
                Recipient      = FormatStringToArrayWithoutDot(model.InternRecipient),
                joinFiles      = files.ToArray(),
                CopyCc         = FormatStringToArray(model.StringCopyTo),
                MailBodyIsHtml = true
            };

            // Si le n° d'employeur trouvé est <> 0 et si nouvelle tâche
            // -> aller mettre ce n° d'employeur dans les pièces jointes
            // Si le n° d'employeur n'a pas déjà été garni
            if (employerNumber != 0 && model.IsNewTask)
            {
                foreach (var currentFile in externMail.joinFiles)
                {
                    if (currentFile.Document == null)
                    {
                        currentFile.Document = new ClDocument();

                        ClEmployerDetail currentEmployer = new ClEmployerDetail();
                        currentEmployer.EmployeurNumber = employerNumber;

                        currentFile.Document.EmployerList    = new ClEmployerDetail[1];
                        currentFile.Document.EmployerList[0] = currentEmployer;

                        currentFile.WithIndexing = true;
                    }
                }
            }


            var conversationIdTechnic = await Task.Run(() => gatewayITask.AddExternMail(taskDocument, externMail, user.Id));

            if (model.TypeOfMessage == 8 && conversationIdTechnic != -1)
            {
                //if draft is created from a draft, the older draft is removed
                if (model.IsDraft && model.TaskContributeId > 0)
                {
                    gatewayITask.DeleteConversation(model.TaskContributeId, user.IdAgent);
                }

                return(new ResultViewModel()
                {
                    NoError = true, Message1 = "Draft Created"
                });
            }

            if (conversationIdTechnic != -1)
            {
                model.Recipient = externMail.Recipient;
                //model.CopyTo = externMail.CopyCc;
                model.Message = externMail.MailBody;

                //Récupérer tout les utilisateurs de Task
                List <ClAgent> allAgentsGroupsList = new List <ClAgent>();

                //Récupération en session des agents
                if (HttpContext.Current.Session["AllAgentsGroupsListTrueIntercept"] == null)
                {
                    allAgentsGroupsList = gatewayITask.GetAllTaskUser(true).ToList();
                    HttpContext.Current.Session["AllAgentsGroupsListTrueIntercept"] = allAgentsGroupsList;
                }
                else
                {
                    allAgentsGroupsList = (List <ClAgent>)HttpContext.Current.Session["AllAgentsGroupsListTrueIntercept"];
                }

                // Boucler sur les personnes en Cc et les retirer si ce sont des utilisateurs de Task
                List <string> CopyCcList = new List <string>();

                foreach (var currentCc in externMail.CopyCc)
                {
                    if (allAgentsGroupsList.Count(p => p.Mail.ToLower() == currentCc.ToLower()) == 0)
                    {
                        CopyCcList.Add(currentCc);
                    }
                }

                model.CopyTo             = CopyCcList.ToArray();
                model.ConversationIdTech = conversationIdTechnic;
                model.UserId             = user.Id;

                var mailReturn = await Task.Run(() => ManageMail.SendMailAndImage(model, user.Email, filesForEmail));

                //element de conversation bien crée et mail bien envoyé
                if (mailReturn)
                {
                    //delete the draft message after sending the mail without errors
                    if (model.IsDraft && model.TaskContributeId > 0)
                    {
                        var draftDeleted = gatewayITask.DeleteConversation(model.TaskContributeId, user.IdAgent);
                    }

                    return(new ResultViewModel
                    {
                        NoError = mailReturn,
                        Message1 = ""
                    });
                }
                else
                {
                    //element de conversation bien crée et PROBLEME envoi mail
                    return(new ResultViewModel
                    {
                        NoError = false,
                        Message1 = "ERROR_SEND_MAIL_AFTER"
                    });
                }
            }

            return(new ResultViewModel
            {
                NoError = false,
                Message1 = "ERROR_OCCURD_RETRY_LATER"
            });
        }
        public static async Task <ResultViewModel> SaveAndSendNewMessage(SendMessageViewModel model, ServiceGateWayClient gatewayITask, TaskUser user, EnvironmentViewModel environment, List <JoinFileViewModel> newFiles)
        {
            var newFilesTojoin     = MapClJoinFileToJoinFileViewModel.Map(newFiles);
            var existingFilesToAdd = await Task.Run(() => gatewayITask.GetJoinFilesByPermId(model.ExistingFilesToJoin.ToArray()));

            var files = newFilesTojoin.ToList();

            foreach (var existing in existingFilesToAdd)
            {
                var f = existing;
                f.PermIdFileAlreadyArchived = f.PermId;
                files.Add(f);
            }

            var cltaskdocument = new ClTaskDocument
            {
                Task = new ClTask
                {
                    TechnicalId    = model.TaskId,
                    Description    = model.TaskDescription,
                    EmployerNumber = model.EmployerNumber,
                    WorkerNumber   = model.WorkerNumber
                }
            };

            var result = new ResultViewModel
            {
                NoError = true
            };
            //bool isOk = true;
            var task = await Task.Run(() => gatewayITask.SearchDocumentTask(model.TaskId, user.Language, true, MapClRessourcesToRessourcesViewModel.Map(user.RessourcesListWithAccess).ToArray(), long.Parse(user.Id)));

            task.CurrentStatus = model.Status;
            if (task.CurrentStatus != 4)
            {
                task.Task.EffectiveEndDate = DateTime.MinValue;
            }
            switch (model.TypeOfMessage)
            {
            case 1:     //Mail provenant de l'extérieur --> on n'enverra pas de mail de ce type
                break;

            case 2:     // commentaire
                Log.Write("SaveAndSendNewMessage", "Conversation", model.TaskId.ToString(), 3, "debut SaveComment");
                result.NoError = await SaveComment(gatewayITask, user, cltaskdocument, files, model);

                Log.Write("SaveAndSendNewMessage", "Conversation", model.TaskId.ToString(), 3, "fin SaveComment");
                if (result.NoError)
                {
                    result.NoError = await Task.Run(() => gatewayITask.UpdateTaskDocument(task, user.Id, user.CurrentEntityNumber, MapClRessourcesToRessourcesViewModel.Map(user.RessourcesListWithAccess).ToArray(), long.Parse(user.Id)));
                }
                break;

            case 3:     //Mail interne
                result.NoError = await SaveInternMessage(gatewayITask, user, cltaskdocument, files, model);

                if (model.AssignToUser)
                {
                    task.Context = int.Parse(model.InternRecipientId);
                }
                if (result.NoError)
                {
                    result.NoError = await Task.Run(() => gatewayITask.UpdateTaskDocument(task, user.Id, user.CurrentEntityNumber, MapClRessourcesToRessourcesViewModel.Map(user.RessourcesListWithAccess).ToArray(), long.Parse(user.Id)));
                }
                break;

            case 8:
            case 10:     //Mail destiné à l'extérieur
                var filesForEmail = GetFilesForEmail(existingFilesToAdd, newFilesTojoin);
                result = await SaveExternMessage(gatewayITask, user, cltaskdocument, files, filesForEmail, model);

                if (result.NoError && !model.IsDirectEmail)
                {
                    result.NoError = await Task.Run(() => gatewayITask.UpdateTaskDocument(task, user.Id, user.CurrentEntityNumber, MapClRessourcesToRessourcesViewModel.Map(user.RessourcesListWithAccess).ToArray(), long.Parse(user.Id)));
                }
                break;
            }
            return(result);
        }
        public static async Task <ConversationViewModel> FillConversationFromTask(long taskId, ServiceGateWayClient gatewayITask, EnvironmentViewModel environnement, TaskUser user, List <ClAgent> fullAgents, ClTaskDocument currentTask = null)
        {
            var model = new ConversationViewModel();
            var task  = new ClTaskDocument();

            //On va chercher les préférences utilisateurs, comme l'affichage chronologique, les couleurs...
            var userPreference = await PreferenceHelper.GetPreferenceSettings(gatewayITask, user);

            //pour pouvoir avoir les quelques infos de la tâche (description, employeur et travailleur de la tâche)
            if (currentTask != null)
            {
                task = currentTask;
            }
            else
            {
                //on va récupérer les documents attachés à la tâche
                task = await Task.Run(() => gatewayITask.SearchDocumentTask(taskId, environnement.language, true,
                                                                            MapClRessourcesToRessourcesViewModel.Map(user.RessourcesListWithAccess).ToArray(), long.Parse(user.Id)));
            }

            //On va cherché les éléments de conversations liés à la tâche et on les trie par date d'envoi
            var contentConversation = gatewayITask.GetTaskConversation(task).OrderBy(a => a.SentDate);


            if (taskId == -1)
            {
                //Actuellement aucunes tâches sans identifiant...une sécurité inutile?
                //todo something
            }
            else
            {
                model.TaskId              = taskId;
                model.CurrentStatus       = task.CurrentStatus;
                model.Description         = task.Task.Description;
                model.TaskEmployerNumber  = task.Task.EmployerNumber;
                model.TaskEmployerName    = task.Task.EmployerDenomination;
                model.TaskWorkerNumber    = task.Task.WorkerNumber;
                model.TaskWorkerName      = task.Task.WorkerName;
                model.DialogDisplayChrono = userPreference.DialogDisplayChrono;
                model.IsStatusVisible     = true;

                //on construit la conversation
                foreach (var elem in contentConversation)
                {
                    //Filtre en fonction des droits de l'utilisateur connecté
                    if (CanSeeMessage(elem, user, gatewayITask))
                    {
                        var senderMail = CreateALiasFormated(elem.AuthorAgent.Mail, elem.AliasFrom);
                        var mess       = new MessageConversationViewModel
                        {
                            TypeOfMessage             = elem.ContributionType.ToString(),
                            DateOfMessage             = elem.SentDate,
                            Sender                    = senderMail,
                            Subject                   = elem.Subject,
                            MessageContentText        = elem.MailBodyText,
                            MessageContentHtml        = elem.MailBody,
                            IsConfidential            = elem.Confidential == 1,
                            FilesAssociatedToMessage  = new List <DocumentViewModel>(),
                            FullHtmlToRecover         = "<div style=\"color:black;\">" + elem.MailBody + "</div>",
                            PermIdMainMessage         = elem.PermIdMainMessage,
                            TechnicalIdContributeTask = elem.IdTechnic,
                            MailBodyIsHtml            = elem.MailBodyIsHtml,
                            AliasCopyCc               = new List <string>(elem.AliasCopyCc),
                            AliasRecipient            = new List <string>(elem.AliasRecipient),
                            AliasFrom                 = elem.AliasFrom
                        };

                        // 10/09/2019, toujours prendre le contenu html du mail
                        if (string.IsNullOrEmpty(mess.MessageContentHtml))
                        {
                            mess.MessageContentHtml = mess.MessageContentText;
                        }

                        // Lors de l'envoi du mail, le tag GroupSMailExternTask a été rajouté
                        // Donc on peut couper pour l'affichage tout ce qui se trouve dans cette Div
                        try
                        {
                            //Nugget pour parcourir HTML sous forme hierarchique
                            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                            doc.LoadHtml(mess.MessageContentHtml);
                            var divs = doc.DocumentNode.SelectNodes("//div");
                            if (divs != null)
                            {
                                foreach (var tag in divs)
                                {
                                    if (tag.Attributes["id"] != null && tag.Attributes["id"].Value.Contains("MailExternTask"))
                                    {
                                        tag.Remove();
                                    }
                                }
                                mess.MessageContentHtml = doc.DocumentNode.InnerHtml;
                            }
                        }
                        catch { }
                        //

                        mess.AgentVm = MapClAgentToAgentViewModel.Map(elem.AuthorAgent);

                        //on construit les CC
                        foreach (var cc in elem.CopyCc)
                        {
                            if (cc != "0")
                            {
                                mess.CopyTo += cc + ", ";
                            }
                        }


                        if (!string.IsNullOrEmpty(mess.CopyTo))
                        {
                            mess.CopyTo = mess.CopyTo.Substring(0, mess.CopyTo.Length);
                        }

                        foreach (var rc in elem.Recipient)
                        {
                            if (rc != "0")
                            {
                                mess.Receiver += rc + ", ";
                            }
                        }

                        if (!string.IsNullOrEmpty(mess.Receiver))
                        {
                            mess.Receiver = mess.Receiver.Substring(0, mess.Receiver.Length);
                        }

                        //Permet de savoir si il y a plus d'une seule addresse dans le to
                        var isManyReceiver = mess.Receiver != null?mess.Receiver.Split(',') : new string [1];

                        List <string> listReceiver = new List <string>(isManyReceiver);

                        //Supprime la derniere cellule car elle est egale a " " comme on split sur les ','
                        listReceiver.RemoveAt(listReceiver.Count() - 1);

                        //savoir si on doit afficher le bouton reply all ou pas
                        mess.CanSeeReplyAllButton = listReceiver.Count() > 1 || mess.CopyTo != null ? true : false;

                        //si ce n'est pas un commentaire
                        if (mess.TypeOfMessage != "2")
                        {
                            var adrTo = CreateChainOfAddressMailWithAlias(elem.AliasRecipient, elem.Recipient);
                            if (adrTo.Length > 0)
                            {
                                //Retire la derniere virgule inutile
                                adrTo = adrTo.Remove(adrTo.Length - 1);
                                mess.MoreInfosAboutMessage = "TO : " + adrTo;
                            }

                            var adrCC = CreateChainOfAddressMailWithAlias(elem.AliasCopyCc, elem.CopyCc);
                            if (adrCC.Length > 0)
                            {
                                //Retire la derniere virgule inutile
                                adrCC = adrCC.Remove(adrCC.Length - 1);
                                mess.MoreInfosAboutMessage += ",CC : " + adrCC;
                            }


                            // Il arrive que des mails ont été archivés sans adresses dans To et sans CC
                            if (mess.MoreInfosAboutMessage != null)
                            {
                                mess.MoreInfosAboutMessage = mess.MoreInfosAboutMessage.Replace(";", ";\n");
                            }
                        }

                        foreach (var file in elem.joinFiles)
                        {
                            mess.FilesAssociatedToMessage.Add(new DocumentViewModel
                            {
                                DocumentName = file.FileName,
                                PermId       = file.PermId
                            });
                        }

                        //Adaptation pour le CSS sous forme de bulle de conversation => preferences
                        switch (elem.ContributionType)
                        {
                        case 1:    //TASK_TYPE_CONTRIBUTION 1 Mail provenant de l'extérieur
                            mess.BubbleCss = "bubble-left mail-content";
                            break;

                        case 2:    //TASK_TYPE_CONTRIBUTION 2 Commentaire
                            mess.BubbleCss = "bubble-comment comment-content";
                            break;

                        case 3:    //TASK_TYPE_CONTRIBUTION 3 Mail interne
                                   //si c'est message interne mais c'est la réponse d'un collègue --> bubble-left-internal
                            mess.BubbleCss = elem.AuthorCreation == user.Id ? "bubble-right-internal dialog-content" : "bubble-left-internal dialog-content";
                            break;

                        case 8:    //TASK_TYPE_CONTRIBUTION 10 Mail destiné à l'extérieur
                            mess.BubbleCss = elem.AuthorCreation == user.Id ? "bubble-right-draft mail-content" : "bubble-left-draft mail-content";
                            break;

                        case 10:    //TASK_TYPE_CONTRIBUTION 10 Mail destiné à l'extérieur
                            mess.BubbleCss = elem.AuthorCreation == user.Id ? "bubble-right-external mail-content" : "bubble-left-external mail-content";
                            break;
                        }
                        model.MessageConversationList.Add(mess);
                    }
                }

                //mettre le dernier mail externe en reply si il existe
                var lastExt = model.MessageConversationList.LastOrDefault(x => x.TypeOfMessage == "1");
                if (lastExt != null)
                {
                    lastExt.LastExternReply = true;
                }

                //mettre le dernier mail interne en reply si il existe
                var lastInt = model.MessageConversationList.LastOrDefault(x => x.TypeOfMessage == "3");
                if (lastInt != null)
                {
                    lastInt.LastInternReply = true;
                }
            }

            model.Environment = new EnvironmentViewModel
            {
                _listLabels = environnement._listLabels,
                language    = environnement.language
            };


            if (userPreference.DialogDisplayChrono)
            {
                model.MessageConversationList = model.MessageConversationList.OrderBy(a => a.DateOfMessage).ToList();
            }
            else
            {
                model.MessageConversationList = model.MessageConversationList.OrderByDescending(a => a.DateOfMessage).ToList();
            }

            return(model);
        }