/// <summary> /// Absorb the boot parameters, deserialize and pass on the messages to the Search Worker /// </summary> public void DoBeginWork(string bootParameter) { bootParameter.ShouldNotBeEmpty(); // Deserialize and determine the boot object _mBootObject = GetBootObject(bootParameter); _mBootObject.ShouldNotBe(null); _mBootObject.TagDetails.ShouldNotBe(null); _mBootObject.TagDetails.Id.ShouldBeGreaterThan(0); _mBootObject.TagDetails.MatterId.ShouldBeGreaterThan(0); _mBootObject.TagDetails.CollectionId.ShouldNotBeEmpty(); _mBootObject.DocumentListDetails.ShouldNotBe(null); _mBootObject.DocumentListDetails.SearchContext.ShouldNotBe(null); _mBootObject.DocumentListDetails.SearchContext.MatterId.ShouldBeGreaterThan(0); _mBootObject.JobScheduleCreatedBy.ShouldNotBeEmpty(); MockSession(_mBootObject.JobScheduleCreatedBy); // Fetch tag details _mTagDetails = RvwTagService.GetTag(_mBootObject.TagDetails.Id.ToString(CultureInfo.InvariantCulture), _mBootObject.TagDetails.CollectionId, _mBootObject.TagDetails.MatterId.ToString( CultureInfo.InvariantCulture)); if (_mTagDetails == null) { throw new Exception("Given tag does not exists"); } if (!_mTagDetails.Status) { throw new Exception(string.Format("Tag {0} does not exists in active state", _mTagDetails.TagDisplayName)); } _mSearchContext = GetSearchContext(_mBootObject, true, false); var documents = GetDocuments(_mSearchContext); if (!documents.Any()) { LogMessage(true, String.Format("Tag Startup Worker : No document(s) qualified to tag {0} for the job run id : {1}", _mTagDetails.Name, PipelineId)); return; } //// Retrieve the total documents qualified _mTotalDocumentCount = documents.Count; var strMsg = String.Format("{0} documents are qualified to tag {1} for the job run id : {2}", _mTotalDocumentCount, _mTagDetails.Name, PipelineId); LogMessage(false, strMsg); // Group the results and send it in batches GroupDocumentsAndSend(documents); }
/// <summary> /// Construct the query to retrive selected documents along with duplicates if required /// </summary> /// <param name="jobParameters">Job parameters</param> /// <returns>Search query string</returns> private static string ConstructSearchQuery(BulkTagJobBusinessEntity jobParameters) { var tmpQuery = string.Empty; var selectionQuery = string.Empty; if (!string.IsNullOrEmpty(jobParameters.DocumentListDetails.SearchContext.Query)) { tmpQuery = jobParameters.DocumentListDetails.SearchContext.Query; } switch (jobParameters.DocumentListDetails.GenerateDocumentMode) { case DocumentSelectMode.UseSelectedDocuments: { //Resetting the tmpQuery to empty string since it is not required when selected documents are sent - //to handle the issue when there are OR operators in the query or the search is done using concept search //and the search term has relevant synonyms tmpQuery = string.Empty; jobParameters.DocumentListDetails.SelectedDocuments.ForEach(d => selectionQuery += string.Format("{0}:\"{1}\" OR ", EVSystemFields.DocumentKey, d)); if (!string.IsNullOrEmpty(selectionQuery)) { selectionQuery = selectionQuery.Substring(0, selectionQuery.LastIndexOf(" OR ", StringComparison.Ordinal)); tmpQuery = string.IsNullOrEmpty(tmpQuery) ? selectionQuery : string.Format("({0} AND {1})", tmpQuery, selectionQuery); } break; } case DocumentSelectMode.QueryAndExclude: { jobParameters.DocumentListDetails.DocumentsToExclude.ForEach(d => selectionQuery += string.Format("(NOT {0}:\"{1}\") AND ", EVSystemFields.DocumentKey, d)); if (!string.IsNullOrEmpty(selectionQuery)) { selectionQuery = selectionQuery.Substring(0, selectionQuery.LastIndexOf(" AND ", System.StringComparison.Ordinal)); tmpQuery = string.IsNullOrEmpty(tmpQuery) ? selectionQuery : string.Format("({0} AND {1})", tmpQuery, selectionQuery); } break; } } return(tmpQuery); }
/// <summary> /// Sets the selected documents for reprocess tagging. /// </summary> /// <param name="jobParameters">The job parameters.</param> private void SetSelectedDocumentsForReprocessTagging(BulkTagJobBusinessEntity jobParameters) { var docs = RVWTagBO.GetDocumentsForReprocessTagging( jobParameters.DocumentListDetails.SearchContext.MatterId, jobParameters.ReprocessJobId, jobParameters.Filters); if (!docs.Any()) { return; } LogMessage(false, string.Format("{0} documents determined for tag reprocessing", docs.Count)); jobParameters.DocumentListDetails.SelectedDocuments.AddRange(docs); }
/// <summary> /// Generate part of notification message common to all events during bulk tagging /// </summary> /// <param name="bulkTagRecord"></param> /// <param name="notificationMessage"></param> private static void GenerateGeneralNotificationDetailsForReviewerBulkTagJob (ActiveJob job, BulkTagJobBusinessEntity bulkTagJobBeo, StringBuilder notificationMessage, JobBusinessEntity jobBeo) { notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageStartTime)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append(HttpUtility.HtmlEncode(jobBeo.JobScheduleStartDate.ConvertToUserTime())); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageEndTime)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append(HttpUtility.HtmlEncode(jobBeo.JobCompletedDate.ConvertToUserTime())); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageLocation)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append(HttpUtility.HtmlEncode(GetTaggingLocation(bulkTagJobBeo))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageTagName)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append(HttpUtility.HtmlEncode(bulkTagJobBeo.TagDetails.Name)); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); }
/// <summary> /// Get the tag location /// </summary> /// <param name="bulkTagRecord"></param> /// <returns></returns> private static string GetTaggingLocation(BulkTagJobBusinessEntity bulkTagJobBeo) { var location = string.Empty; if (!string.IsNullOrEmpty(bulkTagJobBeo.DocumentListDetails.SearchContext.ReviewSetId)) { var reviewSetDetails = ReviewSetBO.GetReviewSetDetails (bulkTagJobBeo.DocumentListDetails.SearchContext.MatterId.ToString(CultureInfo.InvariantCulture), bulkTagJobBeo.DocumentListDetails.SearchContext.ReviewSetId); if (reviewSetDetails != null) { location = reviewSetDetails.ReviewSetName; } } else { var dataSetDetails = DataSetBO.GetDataSetDetailForDataSetId(bulkTagJobBeo.DocumentListDetails.SearchContext.DataSetId); if (dataSetDetails != null) { location = dataSetDetails.FolderName; } } return(location); }
private static string ConstructNotificationBodyForReviewerBulkTag (ActiveJob activeJob, BulkTagJobBusinessEntity bulkTagJobBeo, TagLogBEO tagLogBeo, JobBusinessEntity jobBeo) { //Add notification message to be sent var notificationMessage = new StringBuilder(); notificationMessage.Append(Table); if (bulkTagJobBeo.IsOperationTagging) { notificationMessage.Append(Row); notificationMessage.Append(Header); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageHeadingForTagging)); notificationMessage.Append(CloseHeader); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTagging)); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); GenerateGeneralNotificationDetailsForReviewerBulkTagJob(activeJob, bulkTagJobBeo, notificationMessage, jobBeo); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTaggingDocumentsTagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.DocumentTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTaggingDocumentsAlreadyTagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.AlreadyTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTaggingDocumentsFailed)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.FailedTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); } else { notificationMessage.Append(Row); notificationMessage.Append(Header); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageHeadingForUntagging)); notificationMessage.Append(CloseHeader); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForUntagging)); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); GenerateGeneralNotificationDetailsForReviewerBulkTagJob(activeJob, bulkTagJobBeo, notificationMessage, jobBeo); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForUntaggingDocumentsUnTagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.DocumentTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForUntaggingDocumentsNotUntagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode( (tagLogBeo.FailedTag + tagLogBeo.AlreadyTag).ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); } notificationMessage.Append(CloseTable); return(notificationMessage.ToString()); }
/// <summary> /// Get filtered list of documents from the search context /// </summary> /// <param name="jobParameters">Input parameters of the job</param> /// <param name="isTotalRecall"></param> /// <param name="justCount"></param> /// <returns>List of filtered documents</returns> private DocumentQueryEntity GetSearchContext(BulkTagJobBusinessEntity jobParameters, bool isTotalRecall, bool justCount) { if (!string.IsNullOrEmpty(jobParameters.JobSource) && jobParameters.JobSource.Equals("reprocessfilterdocuments", StringComparison.InvariantCultureIgnoreCase)) { SetSelectedDocumentsForReprocessTagging(jobParameters); } var documentQueryEntity = new DocumentQueryEntity { QueryObject = new SearchQueryEntity { ReviewsetId = jobParameters.DocumentListDetails.SearchContext.ReviewSetId, DatasetId = jobParameters.DocumentListDetails.SearchContext.DataSetId, MatterId = jobParameters.DocumentListDetails.SearchContext.MatterId, IsConceptSearchEnabled = jobParameters.DocumentListDetails.SearchContext.IsConceptSearchEnabled, }, }; #region Initialize Bin filters if (!string.IsNullOrEmpty(jobParameters.DocumentListDetails.SearchContext.BinningState)) { var binquerys = new List <BinFilter>(); string[] separator = { "AND" }; var selectedList = jobParameters.DocumentListDetails.SearchContext.BinningState.Trim() .Split(separator, StringSplitOptions.None); foreach (var query in selectedList) { var bins = query.Split(':'); if (bins.Length > 0) { var binvalue = string.Empty; for (var i = 1; i < bins.Length; i++) { if (binvalue != string.Empty) { binvalue = binvalue + ":"; } binvalue = binvalue + bins[i]; } binquerys.Add(new BinFilter { BinField = bins[0], BinValue = binvalue }); documentQueryEntity.QueryObject.BinFilters.Clear(); documentQueryEntity.QueryObject.BinFilters.AddRange(binquerys); } } } #endregion documentQueryEntity.DocumentCount = justCount ? 1 : 999999999; if (isTotalRecall) { var outputFields = new List <Field>(); outputFields.AddRange(new List <Field> { new Field { FieldName = DcnField }, new Field { FieldName = EVSystemFields.ReviewSetId }, new Field { FieldName = EVSystemFields.FamilyId }, new Field { FieldName = EVSystemFields.DuplicateId } }); documentQueryEntity.OutputFields.AddRange(outputFields); //Populate fetch duplicates fields documentQueryEntity.TotalRecallConfigEntity.IsTotalRecall = true; } documentQueryEntity.QueryObject.QueryList.Clear(); documentQueryEntity.QueryObject.QueryList.Add(new Query { SearchQuery = ConstructSearchQuery(jobParameters) }); documentQueryEntity.SortFields.Add(new Sort { SortBy = Constants.Relevance }); documentQueryEntity.IgnoreDocumentSnippet = true; documentQueryEntity.DocumentStartIndex = 0; return(documentQueryEntity); }
/// <summary> /// Sets the selected documents for reprocess tagging. /// </summary> /// <param name="jobParameters">The job parameters.</param> private void SetSelectedDocumentsForReprocessTagging(BulkTagJobBusinessEntity jobParameters) { var docs = RVWTagBO.GetDocumentsForReprocessTagging( jobParameters.DocumentListDetails.SearchContext.MatterId, jobParameters.ReprocessJobId, jobParameters.Filters); if (!docs.Any()) return; LogMessage(false, string.Format("{0} documents determined for tag reprocessing", docs.Count)); jobParameters.DocumentListDetails.SelectedDocuments.AddRange(docs); }
/// <summary> /// Construct the query to retrive selected documents along with duplicates if required /// </summary> /// <param name="jobParameters">Job parameters</param> /// <returns>Search query string</returns> private static string ConstructSearchQuery(BulkTagJobBusinessEntity jobParameters) { var tmpQuery = string.Empty; var selectionQuery = string.Empty; if (!string.IsNullOrEmpty(jobParameters.DocumentListDetails.SearchContext.Query)) { tmpQuery = jobParameters.DocumentListDetails.SearchContext.Query; } switch (jobParameters.DocumentListDetails.GenerateDocumentMode) { case DocumentSelectMode.UseSelectedDocuments: { //Resetting the tmpQuery to empty string since it is not required when selected documents are sent - //to handle the issue when there are OR operators in the query or the search is done using concept search //and the search term has relevant synonyms tmpQuery = string.Empty; jobParameters.DocumentListDetails.SelectedDocuments.ForEach(d => selectionQuery += string.Format("{0}:\"{1}\" OR ", EVSystemFields.DocumentKey, d)); if (!string.IsNullOrEmpty(selectionQuery)) { selectionQuery = selectionQuery.Substring(0, selectionQuery.LastIndexOf(" OR ", StringComparison.Ordinal)); tmpQuery = string.IsNullOrEmpty(tmpQuery) ? selectionQuery : string.Format("({0} AND {1})", tmpQuery, selectionQuery); } break; } case DocumentSelectMode.QueryAndExclude: { jobParameters.DocumentListDetails.DocumentsToExclude.ForEach(d => selectionQuery += string.Format("(NOT {0}:\"{1}\") AND ", EVSystemFields.DocumentKey, d)); if (!string.IsNullOrEmpty(selectionQuery)) { selectionQuery = selectionQuery.Substring(0, selectionQuery.LastIndexOf(" AND ", System.StringComparison.Ordinal)); tmpQuery = string.IsNullOrEmpty(tmpQuery) ? selectionQuery : string.Format("({0} AND {1})", tmpQuery, selectionQuery); } break; } } return tmpQuery; }
/// <summary> /// Get filtered list of documents from the search context /// </summary> /// <param name="jobParameters">Input parameters of the job</param> /// <param name="isTotalRecall"></param> /// <param name="justCount"></param> /// <returns>List of filtered documents</returns> private DocumentQueryEntity GetSearchContext(BulkTagJobBusinessEntity jobParameters, bool isTotalRecall, bool justCount) { if (!string.IsNullOrEmpty(jobParameters.JobSource) && jobParameters.JobSource.Equals("reprocessfilterdocuments", StringComparison.InvariantCultureIgnoreCase)) { SetSelectedDocumentsForReprocessTagging(jobParameters); } var documentQueryEntity = new DocumentQueryEntity { QueryObject = new SearchQueryEntity { ReviewsetId = jobParameters.DocumentListDetails.SearchContext.ReviewSetId, DatasetId = jobParameters.DocumentListDetails.SearchContext.DataSetId, MatterId = jobParameters.DocumentListDetails.SearchContext.MatterId, IsConceptSearchEnabled = jobParameters.DocumentListDetails.SearchContext.IsConceptSearchEnabled, }, }; #region Initialize Bin filters if (!string.IsNullOrEmpty(jobParameters.DocumentListDetails.SearchContext.BinningState)) { var binquerys = new List<BinFilter>(); string[] separator = { "AND" }; var selectedList = jobParameters.DocumentListDetails.SearchContext.BinningState.Trim() .Split(separator, StringSplitOptions.None); foreach (var query in selectedList) { var bins = query.Split(':'); if (bins.Length > 0) { var binvalue = string.Empty; for (var i = 1; i < bins.Length; i++) { if (binvalue != string.Empty) { binvalue = binvalue + ":"; } binvalue = binvalue + bins[i]; } binquerys.Add(new BinFilter { BinField = bins[0], BinValue = binvalue }); documentQueryEntity.QueryObject.BinFilters.Clear(); documentQueryEntity.QueryObject.BinFilters.AddRange(binquerys); } } } #endregion documentQueryEntity.DocumentCount = justCount ? 1 : 999999999; if (isTotalRecall) { var outputFields = new List<Field>(); outputFields.AddRange(new List<Field> { new Field {FieldName = DcnField}, new Field {FieldName = EVSystemFields.ReviewSetId}, new Field {FieldName = EVSystemFields.FamilyId}, new Field {FieldName = EVSystemFields.DuplicateId} }); documentQueryEntity.OutputFields.AddRange(outputFields); //Populate fetch duplicates fields documentQueryEntity.TotalRecallConfigEntity.IsTotalRecall = true; } documentQueryEntity.QueryObject.QueryList.Clear(); documentQueryEntity.QueryObject.QueryList.Add(new Query { SearchQuery = ConstructSearchQuery(jobParameters) }); documentQueryEntity.SortFields.Add(new Sort { SortBy = Constants.Relevance }); documentQueryEntity.IgnoreDocumentSnippet = true; documentQueryEntity.DocumentStartIndex = 0; return documentQueryEntity; }
/// <summary> /// Get the tag location /// </summary> /// <param name="bulkTagRecord"></param> /// <returns></returns> private static string GetTaggingLocation(BulkTagJobBusinessEntity bulkTagJobBeo) { var location = string.Empty; if (!string.IsNullOrEmpty(bulkTagJobBeo.DocumentListDetails.SearchContext.ReviewSetId)) { var reviewSetDetails = ReviewSetBO.GetReviewSetDetails (bulkTagJobBeo.DocumentListDetails.SearchContext.MatterId.ToString(CultureInfo.InvariantCulture), bulkTagJobBeo.DocumentListDetails.SearchContext.ReviewSetId); if (reviewSetDetails != null) { location = reviewSetDetails.ReviewSetName; } } else { var dataSetDetails = DataSetBO.GetDataSetDetailForDataSetId(bulkTagJobBeo.DocumentListDetails.SearchContext.DataSetId); if (dataSetDetails != null) { location = dataSetDetails.FolderName; } } return location; }
private static string ConstructNotificationBodyForReviewerBulkTag (ActiveJob activeJob, BulkTagJobBusinessEntity bulkTagJobBeo, TagLogBEO tagLogBeo, JobBusinessEntity jobBeo) { //Add notification message to be sent var notificationMessage = new StringBuilder(); notificationMessage.Append(Table); if (bulkTagJobBeo.IsOperationTagging) { notificationMessage.Append(Row); notificationMessage.Append(Header); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageHeadingForTagging)); notificationMessage.Append(CloseHeader); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTagging)); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); GenerateGeneralNotificationDetailsForReviewerBulkTagJob(activeJob, bulkTagJobBeo, notificationMessage, jobBeo); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTaggingDocumentsTagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.DocumentTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTaggingDocumentsAlreadyTagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.AlreadyTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForTaggingDocumentsFailed)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.FailedTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); } else { notificationMessage.Append(Row); notificationMessage.Append(Header); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageHeadingForUntagging)); notificationMessage.Append(CloseHeader); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForUntagging)); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); GenerateGeneralNotificationDetailsForReviewerBulkTagJob(activeJob, bulkTagJobBeo, notificationMessage, jobBeo); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForUntaggingDocumentsUnTagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode(tagLogBeo.DocumentTag.ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); notificationMessage.Append(Row); notificationMessage.Append(Column); notificationMessage.Append(HtmlBold); notificationMessage.Append(HttpUtility.HtmlEncode(NotificationMessageForUntaggingDocumentsNotUntagged)); notificationMessage.Append(HtmlCloseBold); notificationMessage.Append( HttpUtility.HtmlEncode( (tagLogBeo.FailedTag + tagLogBeo.AlreadyTag).ToString(CultureInfo.InvariantCulture))); notificationMessage.Append(CloseColumn); notificationMessage.Append(CloseRow); } notificationMessage.Append(CloseTable); return notificationMessage.ToString(); }