public static ProductionDocumentDetail ConstructProductionModelDocument(ProductionDetailsBEO m_BootParameters) { var m_ProductionDocumentDetail = new ProductionDocumentDetail(); m_ProductionDocumentDetail.MatterId = m_BootParameters.MatterId.ToString(CultureInfo.InvariantCulture); m_ProductionDocumentDetail.CreatedBy = m_BootParameters.CreatedBy; m_ProductionDocumentDetail.DocumentSelectionContext = m_BootParameters.DocumentSelectionContext; m_ProductionDocumentDetail.DocumentExclusionContext = m_BootParameters.DocumentExclusionContext; m_ProductionDocumentDetail.ProductionCollectionId = m_BootParameters.CollectionId; m_ProductionDocumentDetail.Profile = ConvertToProfileDataObjects(m_BootParameters); m_ProductionDocumentDetail.Profile.DatasetId = Convert.ToInt64(null); //TODO: check why we have this GetMatterDatasetDetails(m_ProductionDocumentDetail, m_BootParameters); m_ProductionDocumentDetail.GetText = m_BootParameters.Profile.GetScrubbedText; var productionExtractionPath = Path.Combine(m_BootParameters.Profile.ProductionSetLocation, m_BootParameters.Profile.ProductionSetName); if (!Directory.Exists(productionExtractionPath)) { Directory.CreateDirectory(productionExtractionPath); } m_ProductionDocumentDetail.ExtractionLocation = productionExtractionPath; m_ProductionDocumentDetail.ArchivePath = m_BootParameters.Profile.ProductionSetLocation; m_ProductionDocumentDetail.NearNativeConversionPriority = m_BootParameters.NearNativeConversionPriority; return m_ProductionDocumentDetail; }
/// <summary> /// Rename Produced documents based on Bates Field Value /// </summary> /// <param name="productionDocumentDetail"></param> public List<string> RenameProducedImages(ProductionDocumentDetail productionDocumentDetail) { var producedImages = new List<string>(); if (String.IsNullOrEmpty(productionDocumentDetail.ExtractionLocation)) return null; var files = new DirectoryInfo(productionDocumentDetail.ExtractionLocation). GetFiles(productionDocumentDetail.StartingBatesNumber + ConPagingNameFormat + "*"); foreach (var file in files) { if (file.DirectoryName == null) continue; if (String.IsNullOrEmpty(file.Name)) continue; var fileExtenstion = Path.GetExtension(file.Name); var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file.Name); if (fileNameWithoutExtension == null) continue; var strPageNumber = fileNameWithoutExtension.Replace( productionDocumentDetail. StartingBatesNumber, "").Replace( ConPagingNameFormat, ""); long pageNumebr; if (!long.TryParse(strPageNumber, out pageNumebr)) continue; long batesBeginNumber; var strBatesBeginNumber = productionDocumentDetail. StartingBatesNumber.Replace( productionDocumentDetail.Profile.ProductionPrefix, ""); if (!long.TryParse(strBatesBeginNumber, out batesBeginNumber)) { continue; } var batesRunningNumber = batesBeginNumber + pageNumebr; var fileName = productionDocumentDetail.Profile.ProductionPrefix + batesRunningNumber.ToString("D" + productionDocumentDetail.Profile.ProductionStartingNumber. Length) + fileExtenstion; var imageFilePath = Path.Combine(file.DirectoryName, fileName); if (File.Exists(imageFilePath)) // If same document was reprocessed again using ‘Reprocess Job’, then need to delete old one & keep the latest { File.Delete(imageFilePath); } File.Move(file.FullName, imageFilePath); producedImages.Add(imageFilePath); } return producedImages; }
/// <summary> /// Converts the specified production document detail. /// </summary> /// <param name="productionDocumentDetail">The production document detail.</param> /// <param name="processStatus">The process status.</param> /// <param name="errorReason">The error reason.</param> /// <param name="errorDetails">The error details.</param> /// <returns></returns> private DocumentConversionLogBeo ConvertToDocumentConversionLogBeo(ProductionDocumentDetail productionDocumentDetail, byte processStatus, string errorReason = null, string errorDetails = null) { var documentConversionLogBeo = new DocumentConversionLogBeo { JobRunId = WorkAssignment.JobId, ProcessJobId = WorkAssignment.JobId, Status = processStatus, ErrorReason = errorReason, CollectionId = productionDocumentDetail.OriginalCollectionId, DocumentId = productionDocumentDetail.DocumentId, ModifiedDate = DateTime.UtcNow, ErrorDetails = errorDetails }; return documentConversionLogBeo; }
/// <summary> /// Constructs the audit log. /// </summary> /// <param name="productionDocumentDetail">The production document detail.</param> /// <returns>DocumentIdentifierEntityBEO</returns> private DocumentIdentifierEntityBEO ConstructAuditLog(ProductionDocumentDetail productionDocumentDetail) { if (collectionId == 0) { datasetCollectionGuid.ShouldNotBeEmpty(); collectionId = m_DatasetVaultManager.GetCollectionId(_matterId, new Guid(datasetCollectionGuid)); } var documentIdentifierEntityBeo = new DocumentIdentifierEntityBEO(); if (!string.IsNullOrEmpty(productionDocumentDetail.OriginalCollectionId)) { documentIdentifierEntityBeo.CollectionId = productionDocumentDetail.OriginalCollectionId; } if (!string.IsNullOrEmpty(productionDocumentDetail.DCNNumber)) { documentIdentifierEntityBeo.Dcn = productionDocumentDetail.DCNNumber; } if (!string.IsNullOrEmpty(productionDocumentDetail.OriginalDatasetName)) { documentIdentifierEntityBeo.CollectionName = productionDocumentDetail.OriginalDatasetName; } documentIdentifierEntityBeo.ParentId = collectionId; documentIdentifierEntityBeo.DocumentReferenceId = productionDocumentDetail.OriginalDocumentReferenceId; return documentIdentifierEntityBeo; }
/// <summary> /// constructs document fields and audit log /// </summary> /// <param name="productionDocumentDetail"></param> /// <returns></returns> private List<DocumentFieldsBEO> ConstructDocumentFields(ProductionDocumentDetail productionDocumentDetail) { List<DocumentFieldsBEO> lstDocumentFields = null; var lstProductionFields = productionDocumentDetail.lstProductionFields; var lstDsFeildsBeo = productionDocumentDetail.lstDsFieldsBeo; if (lstProductionFields != null && lstDsFeildsBeo != null) { lstDocumentFields = new List<DocumentFieldsBEO>(); //Bates Number Fieldtype Id-3004 FieldBEO productionFieldBeo = null; productionFieldBeo = lstProductionFields.FirstOrDefault( prodField => prodField.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesNumber)); if (productionFieldBeo != null) { lstDocumentFields.Add(new DocumentFieldsBEO { FieldId = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).ID, FieldType = new FieldDataTypeBusinessEntity { DataTypeId = (Int32) Constants.FieldTypeIds.BatesNumber, DataTypeDisplayValue = Constants.BatesNumber }, FieldValue = !string.IsNullOrWhiteSpace(productionDocumentDetail.AllBates) ? productionDocumentDetail.AllBates : string.Empty, FieldName = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).Name, DocumentReferenceId = productionDocumentDetail.DocumentId }); //Bates Begin Fieldtype Id-3005 productionFieldBeo = lstProductionFields.FirstOrDefault( prodField => prodField.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesBegin)); if (productionFieldBeo != null) { lstDocumentFields.Add(new DocumentFieldsBEO { FieldId = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).ID, FieldType = new FieldDataTypeBusinessEntity { DataTypeId = (Int32) Constants.FieldTypeIds.BatesBegin, DataTypeDisplayValue = Constants.BatesBegin }, FieldValue = !string.IsNullOrWhiteSpace(productionDocumentDetail.StartingBatesNumber) ? productionDocumentDetail.StartingBatesNumber : string.Empty, FieldName = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).Name, DocumentReferenceId = productionDocumentDetail.DocumentId }); } //Bates End Fieldtype Id-3006 productionFieldBeo = lstProductionFields.FirstOrDefault( prodField => prodField.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesEnd)); if (productionFieldBeo != null) { lstDocumentFields.Add(new DocumentFieldsBEO { FieldId = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).ID, FieldType = new FieldDataTypeBusinessEntity { DataTypeId = (Int32) Constants.FieldTypeIds.BatesEnd, DataTypeDisplayValue = Constants.BatesEnd }, FieldValue = !string.IsNullOrWhiteSpace(productionDocumentDetail.EndingBatesNumber) ? productionDocumentDetail.EndingBatesNumber : string.Empty, FieldName = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).Name, DocumentReferenceId = productionDocumentDetail.DocumentId }); } //Bates Range Field Type Id-3007 productionFieldBeo = lstProductionFields.FirstOrDefault( prodField => prodField.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesRange)); if (productionFieldBeo != null) { lstDocumentFields.Add(new DocumentFieldsBEO { FieldId = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).ID, FieldType = new FieldDataTypeBusinessEntity { DataTypeId = (Int32) Constants.FieldTypeIds.BatesRange, DataTypeDisplayValue = Constants.BatesRange }, FieldValue = productionDocumentDetail.StartingBatesNumber + "-" + productionDocumentDetail.EndingBatesNumber, FieldName = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).Name, DocumentReferenceId = productionDocumentDetail.DocumentId }); } } //DPN Fieldtype Id-3008 productionFieldBeo = lstProductionFields.FirstOrDefault( prodField => prodField.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.DPN)); if (productionFieldBeo != null) { lstDocumentFields.Add(new DocumentFieldsBEO { FieldId = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).ID, FieldType = new FieldDataTypeBusinessEntity { DataTypeId = (Int32) Constants.FieldTypeIds.DPN, DataTypeDisplayValue = Constants.DPN }, FieldValue = !string.IsNullOrWhiteSpace(productionDocumentDetail.DocumentProductionNumber) ? productionDocumentDetail.DocumentProductionNumber : string.Empty, FieldName = lstDsFeildsBeo.FirstOrDefault( DsField => DsField.Name.ToLower().Equals(productionFieldBeo.Name.ToLower())).Name, DocumentReferenceId = productionDocumentDetail.DocumentId }); } } return lstDocumentFields; }
private static void GetMatterDatasetDetails(ProductionDocumentDetail m_ProductionDocumentDetail, ProductionDetailsBEO m_BootParameters) { DatasetBEO dataset = DataSetBO.GetDataSetDetailForCollectionId(m_BootParameters.OriginalCollectionId); m_ProductionDocumentDetail.OriginalCollectionId = dataset.RedactableDocumentSetId; //Assign redactable set id as default collection id m_ProductionDocumentDetail.DatasetCollectionId = m_BootParameters.OriginalCollectionId; //Native set collection id m_ProductionDocumentDetail.OriginalDatasetName = dataset.FolderName; m_ProductionDocumentDetail.OriginalDatasetId = (int)dataset.FolderID; m_ProductionDocumentDetail.lstProductionFields = DataSetBO.GetDataSetFields(Convert.ToInt64(m_ProductionDocumentDetail.OriginalDatasetId), m_ProductionDocumentDetail.ProductionCollectionId); m_ProductionDocumentDetail.dataSetBeo = DataSetBO.GetDataSetDetailForDataSetId(Convert.ToInt64(m_ProductionDocumentDetail.OriginalDatasetId)); m_ProductionDocumentDetail.lstDsFieldsBeo = DataSetBO.GetDataSetFields(Convert.ToInt64(m_ProductionDocumentDetail.OriginalDatasetId), m_ProductionDocumentDetail.DatasetCollectionId); m_ProductionDocumentDetail.matterBeo = MatterBO.GetMatterDetails(m_ProductionDocumentDetail.dataSetBeo.ParentID.ToString(CultureInfo.InvariantCulture)); m_ProductionDocumentDetail.SearchServerDetails = ServerBO.GetSearchServer(m_ProductionDocumentDetail.matterBeo.SearchServer.Id); }
private void FillExcludedDoucuments(FilteredDocumentBusinessEntity document, ref List<ProductionDocumentDetail> documents) { using (new EVTransactionScope(TransactionScopeOption.Suppress)) { //Fill production document detail for excluded documents var productionExcludeDocument = new ProductionDocumentDetail { MatterId = _mProductionDocumentDetail.MatterId, CreatedBy = _mProductionDocumentDetail.CreatedBy, DocumentSelectionContext = _mProductionDocumentDetail.DocumentSelectionContext, DatasetCollectionId = _mProductionDocumentDetail.DatasetCollectionId, OriginalCollectionId = _mProductionDocumentDetail.OriginalCollectionId, DocumentExclusionContext = _mProductionDocumentDetail.DocumentExclusionContext, ProductionCollectionId = _mProductionDocumentDetail.ProductionCollectionId, Profile = _mProductionDocumentDetail.Profile }; productionExcludeDocument.Profile.DatasetId = _mProductionDocumentDetail.Profile.DatasetId; productionExcludeDocument.ArchivePath = _mProductionDocumentDetail.ArchivePath; CreateVolume(); productionExcludeDocument.ExtractionLocation = Path.Combine(_mProductionDocumentDetail.ExtractionLocation, _volumeFolderName); productionExcludeDocument.IsVolumeContainExistingDocuments = _volumeContainExistingDocuments; productionExcludeDocument.OriginalDatasetId = _mProductionDocumentDetail.OriginalDatasetId; productionExcludeDocument.OriginalDatasetName = _mProductionDocumentDetail.OriginalDatasetName; productionExcludeDocument.GetText = _mProductionDocumentDetail.GetText; productionExcludeDocument.lstProductionFields = _mProductionDocumentDetail.lstProductionFields; productionExcludeDocument.dataSetBeo = _mProductionDocumentDetail.dataSetBeo; productionExcludeDocument.lstDsFieldsBeo = _mProductionDocumentDetail.lstDsFieldsBeo; productionExcludeDocument.matterBeo = _mProductionDocumentDetail.matterBeo; productionExcludeDocument.SearchServerDetails = _mProductionDocumentDetail.SearchServerDetails; productionExcludeDocument.NearNativeConversionPriority = _mProductionDocumentDetail.NearNativeConversionPriority; productionExcludeDocument.lstProductionFieldValues.AddRange(document.OutPutFields); _taskId += 1; productionExcludeDocument.CorrelationId = _taskId; //If a document is excluded & placeholder page is also not requested then the document is not added as a handler document //Also None of the numbers will be generated for the same if (!productionExcludeDocument.Profile.IsInsertPlaceHolderPage) { return; } SetBatesConfiguration(1, productionExcludeDocument); // We must increment the bates running number so that we get the correct bates field values... _batesRunningNumber++; productionExcludeDocument.DocumentId = document.Id; string originalDocRefId = document.Id; productionExcludeDocument.OriginalDocumentReferenceId = originalDocRefId; productionExcludeDocument.NumberOfPages = 1; productionExcludeDocument.IsDocumentExcluded = true; //Add DPN productionExcludeDocument.DocumentProductionNumber = _dpnPrefix + (productionExcludeDocument.Profile.DpnStartingNumber == null ? string.Empty : GetStartingNumber(_dpnRunningNumber, productionExcludeDocument.Profile.DpnStartingNumber)); _dpnRunningNumber++; productionExcludeDocument.DCNNumber = document.DCN; documents.Add(productionExcludeDocument); } }
/// <summary> /// Logs document count in job log /// </summary> /// <param name="documentDetail"></param> /// <param name="success"></param> /// <param name="message"></param> private void LogMessage(ProductionDocumentDetail documentDetail, bool success, string message) { try { var log = new List<JobWorkerLog<ProductionParserLogInfo>>(); var parserLog = new JobWorkerLog<ProductionParserLogInfo> { JobRunId = (!String.IsNullOrEmpty(PipelineId)) ? Convert.ToUInt32(PipelineId) : 0, CorrelationId = documentDetail.CorrelationId, WorkerRoleType = "prod0fc6-113e-4217-9863-ec58c3f7sw89", WorkerInstanceId = WorkerId, IsMessage = false, Success = success, //!string.IsNullOrEmpty(documentDetail.DocumentProductionNumber) && success, CreatedBy = documentDetail.CreatedBy, LogInfo = new ProductionParserLogInfo { Information = message, //string.IsNullOrEmpty(documentDetail.DocumentProductionNumber) ? "Unable to produce this document" : message, BatesNumber = documentDetail.AllBates, DatasetName = documentDetail.OriginalDatasetName, DCN = documentDetail.DCNNumber, ProductionDocumentNumber = documentDetail.DocumentProductionNumber, ProductionName = documentDetail.Profile.ProfileName } }; // TaskId log.Add(parserLog); SendLog(log); } catch (Exception ex) { ex.AddDbgMsg("Unable to log production documents"); ex.Trace().Swallow(); } }
private void FillSelectedDocuments(IEnumerable<FilteredDocumentBusinessEntity> combinedDocuments, ref List<ProductionDocumentDetail> documents) { using (new EVTransactionScope(TransactionScopeOption.Suppress)) { int runningDocCount = 0; var processSetDocuments = new List<DocumentConversionLogBeo>(); //Fill production document detail for selected documents foreach (FilteredDocumentBusinessEntity document in combinedDocuments) { try { if (document == null) continue; if (runningDocCount == _batchSize) { runningDocCount = 0; Send(documents); documents = new List<ProductionDocumentDetail>(); } if (!document.IsExclude) { var productionSelectedDocument = new ProductionDocumentDetail { MatterId = _mProductionDocumentDetail.MatterId, CreatedBy = _mProductionDocumentDetail.CreatedBy, DocumentSelectionContext = _mProductionDocumentDetail.DocumentSelectionContext, DatasetCollectionId = _mProductionDocumentDetail.DatasetCollectionId, OriginalCollectionId = _mProductionDocumentDetail.OriginalCollectionId, DocumentExclusionContext = _mProductionDocumentDetail.DocumentExclusionContext, ProductionCollectionId = _mProductionDocumentDetail.ProductionCollectionId, Profile = _mProductionDocumentDetail.Profile, ArchivePath = _mProductionDocumentDetail.ArchivePath }; _taskId += 1; productionSelectedDocument.CorrelationId = _taskId; //increment the count for each document productionSelectedDocument.DocumentId = document.Id; string originalDocRefId = document.Id; productionSelectedDocument.OriginalDocumentReferenceId = originalDocRefId; productionSelectedDocument.OriginalDatasetId = _mProductionDocumentDetail.OriginalDatasetId; productionSelectedDocument.OriginalDatasetName = _mProductionDocumentDetail.OriginalDatasetName; productionSelectedDocument.GetText = _mProductionDocumentDetail.GetText; productionSelectedDocument.lstProductionFields = _mProductionDocumentDetail.lstProductionFields; productionSelectedDocument.dataSetBeo = _mProductionDocumentDetail.dataSetBeo; productionSelectedDocument.lstDsFieldsBeo = _mProductionDocumentDetail.lstDsFieldsBeo; productionSelectedDocument.matterBeo = _mProductionDocumentDetail.matterBeo; productionSelectedDocument.SearchServerDetails = _mProductionDocumentDetail.SearchServerDetails; productionSelectedDocument.NearNativeConversionPriority = _mProductionDocumentDetail.NearNativeConversionPriority; productionSelectedDocument.lstProductionFieldValues.AddRange(document.OutPutFields); var numberOfPagesInDoc = GetNumberOfPagesInDocument(productionSelectedDocument, originalDocRefId, document); CreateVolume(); productionSelectedDocument.ExtractionLocation = Path.Combine(_mProductionDocumentDetail.ExtractionLocation, _volumeFolderName); productionSelectedDocument.IsVolumeContainExistingDocuments = _volumeContainExistingDocuments; SetBatesConfiguration(numberOfPagesInDoc, productionSelectedDocument); _batesRunningNumber += numberOfPagesInDoc; //For bates number //Add DPN only when xdl exists i.e numberOfPagesInDoc is not zero if (numberOfPagesInDoc > 0) { productionSelectedDocument.DocumentProductionNumber = _dpnPrefix + (productionSelectedDocument. Profile. DpnStartingNumber == null ? string.Empty : GetStartingNumber( _dpnRunningNumber, productionSelectedDocument . Profile. DpnStartingNumber)); _dpnRunningNumber++; productionSelectedDocument.DCNNumber = document.DCN; documents.Add(productionSelectedDocument); } else { processSetDocuments.Add(ConvertToDocumentConversionLogBeo(document, EVRedactItErrorCodes.Failed, EVRedactItErrorCodes.XdlFileMissingReasonId) ); //Mark document with no binaries as failed with the reason can not find file LogMessage(productionSelectedDocument, false, string.Format("Document with DCN:{0} is {1}{2}", document.DCN, Constants.ProductionPreFailure, Constants.EmptyPagesInDoc)); } } else { FillExcludedDoucuments(document, ref documents); } runningDocCount = runningDocCount + 1; } catch (Exception ex) { processSetDocuments.Add(ConvertToDocumentConversionLogBeo(document, EVRedactItErrorCodes.Failed, EVRedactItErrorCodes.FailedToSendFile)); //If there is a problem in processing one document , continue with other documents ex.Trace().Swallow(); LogMessage(false, string.Format("Document with DCN:{0} is {1}-{2}", document.DCN, Constants.ProductionPreFailure, ex.ToUserString())); } } if (documents.Count > 0) { Send(documents); } BulkInsertProcessSetDocuments(processSetDocuments); } }
/// <summary> /// Get header footer string /// </summary> /// <param name="headerFooter">production header footer</param> /// <param name="jobParameters">job parameters</param> /// <returns> /// header footer string /// </returns> private string GetHeaderFooterString(ProductionSetHeaderFooter headerFooter, ProductionDocumentDetail jobParameters) { try { headerFooter.ShouldNotBe(null); ProductionProfile profile = jobParameters.Profile; switch (headerFooter.Option) { case HeaderFooterOptions.Text: if (!headerFooter.IsIncrementNeededInText) { return (headerFooter.TextPrefix == null ? string.Empty : InsertLineBreaks(CleanInvalidXmlChars(headerFooter.TextPrefix)) + (headerFooter.TextStartingNumber ?? string.Empty)); } return string.Format(Constants.BatesFormat, (headerFooter.TextPrefix == null ? string.Empty : InsertLineBreaks(CleanInvalidXmlChars(headerFooter.TextPrefix))), (headerFooter.TextStartingNumber == null ? string.Empty : GetStartingNumber(jobParameters.StartBatesRunningNumber, headerFooter.TextStartingNumber))); case HeaderFooterOptions.DateAndTime: return Constants.DateTimeFormat; case HeaderFooterOptions.Date: return Constants.DateFormat; case HeaderFooterOptions.Time: return Constants.TimeFormat; case HeaderFooterOptions.DocumentProductionNumber: return jobParameters.DocumentProductionNumber; case HeaderFooterOptions.PageNumber: return Constants.PageNumberFormat; case HeaderFooterOptions.ProductionNumber: return string.Format(Constants.BatesFormat, (profile.ProductionPrefix ?? string.Empty), (profile.ProductionStartingNumber == null ? string.Empty : GetStartingNumber(jobParameters.StartBatesRunningNumber, profile.ProductionStartingNumber))); case HeaderFooterOptions.DatasetField: RVWDocumentBEO document = DocumentBO.GetDocumentDataViewFromVault(jobParameters.MatterId, jobParameters.DatasetCollectionId, jobParameters.OriginalDocumentReferenceId, jobParameters.CreatedBy, true); if (document.FieldList != null && document.FieldList.Count > 0) { RVWDocumentFieldBEO field = document.FieldList.FirstOrDefault(x => x.FieldId == headerFooter.DatasetFieldSelected); if (field != null) { //If user configures bates and dpn fields while scheduling the production job //The field values for the bats and dpn wont exists since we create bates and dpn fields on the creation of production set //and we can update the fields values of those fields only when document binary create and it is done in production vault and velocty worker //so using production document details which will have dpn and bates field values if (_lstBatesAndDpnFieldTypes.Contains(field.FieldType.DataTypeId)) { if (string.IsNullOrEmpty(field.FieldValue) || jobParameters.Profile.ProfileId > 0) { GetFieldVauleForDpnAndBates(jobParameters, field); } } } if (field != null && !string.IsNullOrEmpty(field.FieldValue)) { return CleanInvalidXmlChars(field.FieldValue); } } break; default: return string.Empty; } } catch (Exception ex) { Tracer.Info("Production Preprocess Worker: GetHeaderFooterString() Exception details: {0}", ex); throw; } return string.Empty; }
/// <summary> /// Create the header footer config file for the document /// </summary> /// <param name="sourcePath">Source path.</param> /// <param name="jobParameters">The job parameters.</param> /// <returns> /// Path of the created header footer config xml file /// </returns> private string CreateSecurityFile(string sourcePath, ProductionDocumentDetail jobParameters) { try { string topLeftString = string.Empty; string topCenterString = string.Empty; string topRightString = string.Empty; string bottomLeftString = string.Empty; string bottomCenterString = string.Empty; string bottomRightString = string.Empty; string fontColor = string.Empty; string fontString = string.Empty; string fontHeight = string.Empty; string fontStyle = string.Empty; string newSecurityFile = sourcePath + Guid.NewGuid(); IGCSecurityDocument securityDocument = IGCSecurityDocumentFactory.GetIGCSecurityDocument(); ProductionProfile profile = jobParameters.Profile; ProductionSetHeaderFooterFont font = profile.HeaderFooterFontSelection; ProductionSetHeaderFooter topLeft = profile.LeftHeader; ProductionSetHeaderFooter topCenter = profile.MiddleHeader; ProductionSetHeaderFooter topRight = profile.RightHeader; ProductionSetHeaderFooter bottomLeft = profile.LeftFooter; ProductionSetHeaderFooter bottomCenter = profile.MiddleFooter; ProductionSetHeaderFooter bottomRight = profile.RightFooter; if (font != null) { fontColor = font.HeaderFooterColor ?? string.Empty; fontString = font.HeaderFooterFont ?? string.Empty; fontHeight = font.HeaderFooterFontSize; fontStyle = ((int)font.HeaderFooterStyle).ToString(CultureInfo.InvariantCulture); } if (topLeft != null) topLeftString = GetHeaderFooterString(topLeft, jobParameters); if (topCenter != null) topCenterString = GetHeaderFooterString(topCenter, jobParameters); if (topRight != null) topRightString = GetHeaderFooterString(topRight, jobParameters); if (bottomLeft != null) bottomLeftString = GetHeaderFooterString(bottomLeft, jobParameters); if (bottomCenter != null) bottomCenterString = GetHeaderFooterString(bottomCenter, jobParameters); if (bottomRight != null) bottomRightString = GetHeaderFooterString(bottomRight, jobParameters); ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).IsoBannerColor[0].@string = fontColor; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).IsoBannerFont[0].@string = fontString; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).IsoBannerFontHeight[0].@string = fontHeight; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).IsoBannerFontStyle[0].@string = fontStyle; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).TopLeft[0].@string = topLeftString; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).TopCenter[0].@string = topCenterString; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).TopRight[0].@string = topRightString; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).BottomLeft[0].@string = bottomLeftString; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).BottomCenter[0].@string = bottomCenterString; ((IGCSecurityDocumentIsoBanners)(securityDocument.Items[3])).BottomRight[0].@string = bottomRightString; SaveSecurityFile(newSecurityFile, securityDocument); return newSecurityFile; } catch (Exception ex) { Tracer.Error("Production Preprocess Worker: CreateSecurityFile() : {0}, Exception details: {1}", sourcePath, ex.ToDebugString()); throw; } }
/// <summary> /// Get the header footer config file for the document /// </summary> /// <param name="sourcePath">Source path.</param> /// <param name="jobParameters">Job Parameters.</param> /// <returns> /// Path of the created header footer config xml file /// </returns> public string GetSecurityFile(string sourcePath, ProductionDocumentDetail jobParameters) { try { ProductionProfile profile = jobParameters.Profile; if (profile == null) { return string.Empty; } string securityFile = CreateSecurityFile(sourcePath, jobParameters); return securityFile; } catch (Exception ex) { Tracer.Info("ProductionPreprocessWorker:GetSecurityFile() Sourcepath: {0}, Exception details: {1}", sourcePath, ex.ToDebugString()); throw; } }
/// <summary> /// Method to create the source files - .xdl,.xrl,header footer config /// </summary> /// <param name="sourcePath">Path of the source folder.</param> /// <param name="jobParameters">Job Parameters.</param> /// <param name="dcnNumber">The DCN number.</param> /// <returns> /// Query string with source, markup and headerfooter config file /// </returns> private string CreateSourceFiles(string sourcePath, ProductionDocumentDetail jobParameters, string dcnNumber) { var queryString = new StringBuilder(Constants.QueryStringSourcePrefix); //.xdl file path is appended or html file path appended in case of place holder file if (jobParameters.IsDocumentExcluded) { queryString.Append(GetPlaceHolderFile(sourcePath, jobParameters, dcnNumber)); } else if (_documentBinary != null && _documentBinary.Count > 0) { List<DocumentBinaryEntity> docBinaries = _documentBinary.Where(f => f.DocumentReferenceId == jobParameters.OriginalDocumentReferenceId).ToList(); foreach (DocumentBinaryEntity docBinary in docBinaries) { //Write the file .xdl, .zdl, .idx to the source path ByteArrayToFile(sourcePath + docBinary.BinaryReferenceId, docBinary.DocumentBinary()); } queryString.Append(sourcePath + "document.xdl"); //Document.xdl is common for all binary document } else { Tracer.Error("Unable to get place holder or main igc file for job run id: {0}", PipelineId); } //Create the markup .xrl files on disk(source path) try { if (!jobParameters.IsDocumentExcluded) //if document is excluded then do not include the markup { string markupFile = GetMarkUpFile(sourcePath, jobParameters); if (!String.IsNullOrEmpty(markupFile)) { queryString.Append(Constants.QueryStringMarkupFileNamePrefix); queryString.Append(markupFile); } } } catch (Exception ex) { ex.AddUsrMsg("Unable to get markup files for job run id: {0}", PipelineId); ex.Trace().Swallow(); ReportToDirector(ex); } //Create the header footer config file on disk(source path) try { string headerFooterConfigFile = GetSecurityFile(sourcePath, jobParameters); if (!String.IsNullOrEmpty(headerFooterConfigFile)) { queryString.Append(Constants.QueryStringSecurityXmlFileNamePrefix); queryString.Append(headerFooterConfigFile); } } catch (Exception ex) { ex.AddUsrMsg("Unable to header footer files for job run id: {0}", PipelineId); ex.Trace().Swallow(); ReportToDirector(ex); } //fit within banners queryString.Append(Constants.QueryStringFitWithinBannersSetToTrue); return queryString.ToString(); }
/// <summary> /// Construct Log Message and Call Log pipe /// </summary> private void LogMessage(ProductionDocumentDetail documentDetail, bool success, string message) { try { var log = new List<JobWorkerLog<ProductionParserLogInfo>>(); var parserLog = new JobWorkerLog<ProductionParserLogInfo> { JobRunId = (!String.IsNullOrEmpty(PipelineId)) ? Convert.ToUInt32(PipelineId) : 0, CorrelationId = documentDetail.CorrelationId, WorkerRoleType = Constants.ProductionPreProcessRoleId, WorkerInstanceId = WorkerId, IsMessage = false, Success = success, //!string.IsNullOrEmpty(documentDetail.DocumentProductionNumber) && success, CreatedBy = documentDetail.CreatedBy, LogInfo = new ProductionParserLogInfo { Information = message, //string.IsNullOrEmpty(documentDetail.DocumentProductionNumber) ? "Unable to produce this document" : message, BatesNumber = documentDetail.AllBates, DatasetName = documentDetail.OriginalDatasetName, DCN = documentDetail.DCNNumber, ProductionDocumentNumber = documentDetail.DocumentProductionNumber, ProductionName = documentDetail.Profile.ProfileName } }; // TaskId log.Add(parserLog); SendLog(log); } catch (Exception exception) { Tracer.Error("Production Preprocess Worker: Unable to log message. Exception details: {0}", exception); throw; } }
private void LogMessage(ProductionDocumentDetail documentDetail, bool success, string message, bool isMessage) { const string roleId = "prod0fc6-113e-4217-9863-ec58c3f7yz89"; var log = new List<JobWorkerLog<ProductionParserLogInfo>>(); var parserLog = new JobWorkerLog<ProductionParserLogInfo> { JobRunId = (!String.IsNullOrEmpty(PipelineId)) ? Convert.ToUInt32(PipelineId) : 0, CorrelationId = documentDetail.CorrelationId, WorkerRoleType = roleId, WorkerInstanceId = WorkerId, IsMessage = isMessage, Success = success, CreatedBy = documentDetail.CreatedBy, LogInfo = new ProductionParserLogInfo { Information = message, BatesNumber = documentDetail.AllBates, DatasetName = documentDetail.OriginalDatasetName, DCN = documentDetail.DCNNumber, ProductionDocumentNumber = documentDetail.DocumentProductionNumber, ProductionName = documentDetail.Profile.ProfileName } }; log.Add(parserLog); SendLog(log); }
/// <summary> /// Begins the work. /// </summary> protected override void BeginWork() { base.BeginWork(); _mBootParameters = GetProductionDetailsBusinessEntity(BootParameters); _mBootParameters.ShouldNotBe(null); _mBootParameters.Profile.ShouldNotBe(null); _mBootParameters.Profile.ProductionSetName.ShouldNotBeEmpty(); if (!Directory.Exists(_mBootParameters.Profile.ProductionSetLocation)) { Tracer.Warning(Constants.ProductionsetStartError); LogMessage(false, ConMessageProductionSetLocation); throw new Exception(ConMessageProductionSetLocation); } _vaultManager = EVUnityContainer.Resolve<IDocumentVaultManager>(Constants.DocumentVaultManager); _mProductionDocumentDetail = ProductionStartupHelper.ConstructProductionModelDocument(_mBootParameters); _batesPrefix = _mProductionDocumentDetail.Profile.ProductionPrefix ?? string.Empty; _dpnPrefix = _mProductionDocumentDetail.Profile.DpnPrefix ?? string.Empty; _mCreatedBy = _mBootParameters.CreatedBy; _mDatasetId = _mBootParameters.SearchCriteria.SelectedDatasets[0]; _isPathValid = true; GetVolumeSettings(_mProductionDocumentDetail.ExtractionLocation); var dataset = DataSetBO.GetDataSetDetailForDataSetId(Convert.ToInt64(_mDatasetId)); var field = dataset.DatasetFieldList.FirstOrDefault(f => f.FieldType.DataTypeId == Constants.DCNFieldTypeId); if (field != null) _dcnField = field.Name; MockSession(); //CNEV3.1 - Design Specification - Production update - Call Production BO methods for creating the production tags //CNEV3.1 - Design Specification - Production update - Refactor the worker such a way that worker is just a shim and it just calls the respective business methods ReadProductionBatchSize(); }
/// <summary> /// Get Field Vaule For DpnAndBates /// </summary> /// <param name="productionDocumentDetail">production document detail</param> /// <param name="fieldSelected">field Selected </param> /// <returns></returns> private void GetFieldVauleForDpnAndBates(ProductionDocumentDetail productionDocumentDetail, RVWDocumentFieldBEO fieldSelected) { switch (fieldSelected.FieldType.DataTypeId) { case (Int32)Constants.FieldTypeIds.DPN: fieldSelected.FieldValue = productionDocumentDetail.DocumentProductionNumber; break; case (Int32)Constants.FieldTypeIds.BatesBegin: fieldSelected.FieldValue = productionDocumentDetail.StartingBatesNumber; break; case (Int32)Constants.FieldTypeIds.BatesEnd: fieldSelected.FieldValue = productionDocumentDetail.EndingBatesNumber; break; case (Int32)Constants.FieldTypeIds.BatesRange: var batesRange = new StringBuilder(productionDocumentDetail.StartingBatesNumber); batesRange.Append(Constants.UnderScore); batesRange.Append(productionDocumentDetail.EndingBatesNumber); fieldSelected.FieldValue = batesRange.ToString(); break; default: fieldSelected.FieldValue = fieldSelected.FieldValue; break; } }
/// <summary> /// Gets the number of pages in document. /// </summary> /// <param name="productionSelectedDocument">The production selected document.</param> /// <param name="originalDocRefId">The original document reference identifier.</param> /// <param name="document">The document.</param> /// <returns></returns> private int GetNumberOfPagesInDocument(ProductionDocumentDetail productionSelectedDocument, string originalDocRefId, FilteredDocumentBusinessEntity document) { var numberOfPagesInDoc = 0; var getDocumentSetType = DocumentBO.GetDocumentSetType(productionSelectedDocument.OriginalCollectionId); getDocumentSetType.ShouldNotBe(null); FieldResult fieldResults; switch (getDocumentSetType.DocumentSetTypeId) { case ImageSetTypeId: fieldResults = document.OutPutFields.FirstOrDefault(f => f.Name == EVSystemFields.PagesImages); if (fieldResults != null && !string.IsNullOrEmpty(fieldResults.Value)) numberOfPagesInDoc = Convert.ToInt32(fieldResults.Value); break; case NativeSetTypeId: fieldResults = document.OutPutFields.FirstOrDefault(f => f.Name == EVSystemFields.PagesNatives); if (fieldResults != null && !string.IsNullOrEmpty(fieldResults.Value)) numberOfPagesInDoc = Convert.ToInt32(fieldResults.Value); break; default: numberOfPagesInDoc = CountPagesInDocument(productionSelectedDocument.MatterId, productionSelectedDocument.OriginalCollectionId, originalDocRefId); break; } return numberOfPagesInDoc; }
/// <summary> /// Create the markup file for document /// </summary> /// <param name="sourcePath">Source Path</param> /// <param name="jobBusinessEntity">The job business entity.</param> /// <returns> /// The markup file path /// </returns> public string GetMarkUpFile(string sourcePath, ProductionDocumentDetail jobBusinessEntity) { try { //Check if markup is needed ProductionProfile profile = jobBusinessEntity.Profile; if (profile == null || !profile.IsBurnMarkups) { return string.Empty; } string markupFile = string.Empty; var documentMetaDataBusinessEntity = new DocumentMetaDataBEO { CollectionId = jobBusinessEntity.OriginalCollectionId, DocumentReferenceId = jobBusinessEntity.OriginalDocumentReferenceId, MatterId = jobBusinessEntity.MatterId }; RVWMarkupBEO redActionBusinessEntity = DocumentBO.GetRedactionXml(jobBusinessEntity.MatterId.Trim(), documentMetaDataBusinessEntity.CollectionId, documentMetaDataBusinessEntity.DocumentReferenceId); //If markup file exists write to disk if (redActionBusinessEntity != null && !string.IsNullOrEmpty(redActionBusinessEntity.MarkupXml)) { //Add the version string string markupXmlText = Constants.xmlVersionString.Replace(Constants.Slash, string.Empty) + redActionBusinessEntity.MarkupXml; //Apply user selections like to include or exclude markups XmlDocument markupXml = ApplyUserSelections(markupXmlText, profile); markupFile = sourcePath + Guid.NewGuid(); markupXml.Save(markupFile); } return markupFile; } catch (Exception ex) { ex.AddDbgMsg("ProductionPreprocessWorker:GetMarkUpFile() Sourcepath:{0}", sourcePath); throw; } }
private void SetBatesConfiguration(int numberOfPagesInDoc, ProductionDocumentDetail productionSelectedDocument) { productionSelectedDocument.NumberOfPages = numberOfPagesInDoc; productionSelectedDocument.StartBatesRunningNumber = _batesRunningNumber; //For bates number //Form a comma seperated list of bates numbers productionSelectedDocument.AllBates = GetAllBatesInRange(_batesPrefix, productionSelectedDocument.Profile.ProductionStartingNumber, productionSelectedDocument.StartBatesRunningNumber, numberOfPagesInDoc); productionSelectedDocument.StartingBatesNumber = _batesPrefix + (productionSelectedDocument.Profile.ProductionStartingNumber == null ? string.Empty : GetStartingNumber(Convert.ToInt64(productionSelectedDocument.StartBatesRunningNumber), productionSelectedDocument.Profile.ProductionStartingNumber)); productionSelectedDocument.EndingBatesNumber = _batesPrefix + (productionSelectedDocument.Profile.ProductionStartingNumber == null ? string.Empty : GetStartingNumber(Convert.ToInt64(productionSelectedDocument.StartBatesRunningNumber) + numberOfPagesInDoc - 1, productionSelectedDocument.Profile.ProductionStartingNumber)); }
/// <summary> /// Create the Place holder files in html format files /// </summary> /// <param name="sourcePath">Source path</param> /// <param name="productionDocument">The production document.</param> /// <param name="dcnNumber">The DCN number.</param> /// <returns> /// The path of the .xdl file created /// </returns> public string GetPlaceHolderFile(string sourcePath, ProductionDocumentDetail productionDocument, string dcnNumber) { try { var filePath = string.Format("{0}{1}.html", sourcePath, Guid.NewGuid()); var bootParams = GetBootParameters(); var placeholderHtml = ProductionBO.GetPlaceHolderHtml(bootParams.Profile.PlaceHolderText, productionDocument.PlaceHolderFieldValues, productionDocument.DocumentProductionNumber, productionDocument.AllBates, productionDocument.StartingBatesNumber, productionDocument.EndingBatesNumber); File.WriteAllText(filePath, placeholderHtml, Encoding.UTF8); return filePath; } catch (Exception exception) { Tracer.Info("ProductionPreprocessWorker:GetPlaceHolderFile() SourcePath:{0}, DCN:{1}, Exception details:{2}", sourcePath, dcnNumber, exception); throw; } }
/// <summary> /// Convert the document to the ProductionDocumentDetail that can be used by ProductionNearNativeConversionHelper class /// </summary> /// <param name="document">The document</param> /// <param name="modelDoc">The model document</param> private static ProductionDocumentDetail ConvertToProductionDocumentDetail( ReconversionProductionDocumentBEO document, ProductionDocumentDetail modelDoc) { var pDoc = new ProductionDocumentDetail { MatterId = modelDoc.MatterId, CreatedBy = modelDoc.CreatedBy, DocumentSelectionContext = modelDoc.DocumentSelectionContext, DatasetCollectionId = modelDoc.DatasetCollectionId, OriginalCollectionId = modelDoc.OriginalCollectionId, DocumentExclusionContext = modelDoc.DocumentExclusionContext, ProductionCollectionId = modelDoc.ProductionCollectionId, Profile = modelDoc.Profile, ArchivePath = modelDoc.ArchivePath, OriginalDatasetId = modelDoc.OriginalDatasetId, OriginalDatasetName = modelDoc.OriginalDatasetName, GetText = modelDoc.GetText, lstProductionFields = modelDoc.lstProductionFields, dataSetBeo = modelDoc.dataSetBeo, lstDsFieldsBeo = modelDoc.lstDsFieldsBeo, matterBeo = modelDoc.matterBeo, SearchServerDetails = modelDoc.SearchServerDetails }; //same info for all docs //pDoc.ManageShareRootPath = modelDoc.ManageShareRootPath; pDoc.GetText = modelDoc.GetText; //pupulate from document pDoc.DocumentId = document.DocumentId; pDoc.OriginalDocumentReferenceId = document.DocumentId; pDoc.DCNNumber = document.DCNNumber; //populdate bates pDoc.StartingBatesNumber = document.StartingBatesNumber; pDoc.EndingBatesNumber = document.EndingBatesNumber; //comma seperated list of bates numbers pDoc.AllBates = document.AllBates; //get the number of pages by counting all bates if (document.AllBates != null) pDoc.NumberOfPages = (document.AllBates.Split(new char[] {','})).Length; //popudate DPN pDoc.DocumentProductionNumber = document.DocumentProductionNumber; //set NearNativeConversionPriority pDoc.NearNativeConversionPriority = document.NearNativeConversionPriority; //get the directory for the production location; ProductionPath contain the full path, including the file name if (String.IsNullOrEmpty(document.ProductionPath)) return pDoc; pDoc.ExtractionLocation = Path.GetDirectoryName(document.ProductionPath); return pDoc; }
/// <summary> /// Converts to document conversion log beo. /// </summary> /// <param name="productionDocumentDetail">The production document detail.</param> /// <param name="status">The status.</param> /// <param name="reasonId">The reason id.</param> /// <returns></returns> private DocumentConversionLogBeo ConvertToDocumentConversionLogBeo(ProductionDocumentDetail productionDocumentDetail, byte status, short reasonId) { if (productionDocumentDetail == null || WorkAssignment == null) return null; var documentConversionLogBeo = new DocumentConversionLogBeo { DocumentId = productionDocumentDetail.DocumentId, CollectionId = productionDocumentDetail.OriginalCollectionId, DCN =productionDocumentDetail.DCNNumber, ProcessJobId = WorkAssignment.JobId, JobRunId = WorkAssignment.JobId, Status = status, ReasonId = reasonId, ModifiedDate = DateTime.UtcNow }; return documentConversionLogBeo; }
/// <summary> /// Re name produced image(s) based on Bates Number /// </summary> private void RenameImagesBasedOnBatesNumber(ProductionDocumentDetail productionDocumentDetail) { try { if (!productionDocumentDetail.Profile.IsOneImagePerPage || String.IsNullOrEmpty(productionDocumentDetail.StartingBatesNumber)) return; if (string.IsNullOrEmpty(productionDocumentDetail.Profile.ProductionPrefix) || string.IsNullOrEmpty(productionDocumentDetail.Profile.ProductionStartingNumber)) return; var productionConversionHelper = new ProductionConversionHelper(); var producedImages = productionConversionHelper.RenameProducedImages(productionDocumentDetail); if (!producedImages.Any()) return; productionConversionHelper.UpdateProducedImageFilePath( productionDocumentDetail.DocumentId, productionDocumentDetail.ProductionCollectionId, _matterId, producedImages, productionDocumentDetail.CreatedBy); } catch (Exception exception) { //Log the error message for failed documents var message = ConErrorOnRenameImage + productionDocumentDetail.DCNNumber; LogMessage(productionDocumentDetail, false, message, false); //continue the production process with out rename images exception.Trace().Swallow(); } }
/// <summary> /// Helper method to construct the fields to update in search index /// </summary> /// <param name="document"></param> /// <param name="productionFields"></param> /// <param name="indexFields"></param> private void ConstructIndexFields(ProductionDocumentDetail document, List<DocumentFieldsBEO> productionFields, ref Dictionary<string, List<KeyValuePair<string, string>>> indexFields) { //determine the indexName for bate fields var indexBateFieldNames = document.lstDsFieldsBeo.Where(f => f.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesNumber) || f.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesBegin) || f.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesEnd) || f.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.BatesRange) || f.FieldType.DataTypeId == Convert.ToInt32(Constants.FieldTypeIds.DPN)).Select( f => f.Name).ToList(); var docFields = new List<KeyValuePair<string, string>>(); //loop through all the bates & dpn fields in dataset foreach (var bateField in indexBateFieldNames) { var lstFields = document.Fields.FirstOrDefault(f => f.Key == bateField); var field = productionFields.FirstOrDefault(f => f.FieldName == bateField); if (lstFields.Key != null) { //determine if there is change in value if (field != null && lstFields.Value != field.FieldValue) { docFields.Add(new KeyValuePair<string, string>(bateField, string.Format("{0},{1}", lstFields.Value, field.FieldValue))); } else { docFields.Add(new KeyValuePair<string, string>(bateField, lstFields.Value)); } } else { if (field != null) docFields.Add(new KeyValuePair<string, string>(bateField, field.FieldValue)); } } indexFields.Add(document.DocumentId, docFields); }