/// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        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>
        /// 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>
      /// 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;
      }
      /// <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);
      }
      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();
        }