public override async Task Execute(CommandModel commandModel) { try { if (!(commandModel is CommandConfigureArchiveForPreservation)) { _logger.Error($"Command is not of type {nameof(CommandConfigureArchiveForPreservation)}"); return; } CommandConfigureArchiveForPreservation @command = commandModel as CommandConfigureArchiveForPreservation; await SendNotification(command.ReferenceId, $"Inizio attività di configurazione per l'archivio con id {command.IdArchive}", NotifyLevel.Info); DocumentArchive currentArchive = ArchiveService.GetArchive(command.IdArchive); if (currentArchive == null) { _logger.Error($"Archive with Id {command.IdArchive} not found"); throw new Exception($"Non è stato trovato un archivio con ID {command.IdArchive}"); } Company currentCompany = ArchiveService.GetCompany(command.IdCompany); if (currentCompany == null) { _logger.Error($"Company with Id {command.IdCompany} not found"); throw new Exception($"Non è stata trovata una azienda con ID {command.IdCompany}"); } BindingList <DocumentAttribute> archiveAttributes = AttributeService.GetAttributesFromArchive(command.IdArchive); if (archiveAttributes == null || archiveAttributes.Count == 0) { _logger.Error($"There aren't attributes for archive with Id {command.IdArchive}"); throw new Exception($"Non sono stati trovati attributi per l'archivio con ID {command.IdArchive}"); } if (string.IsNullOrEmpty(currentArchive.PathPreservation)) { _logger.Error($"PathPreservation is null for archive with Id {command.IdArchive}"); throw new Exception($"Non è stato definito il percorso di conservazione per l'archivio con ID {command.IdArchive}"); } DocumentAttribute mainDateAttribute = archiveAttributes.SingleOrDefault(x => x.IsMainDate == true); if (mainDateAttribute == null) { _logger.Error($"MainDate attribute is not defined for archive with Id {command.IdArchive}"); throw new Exception($"Non è stato definito l'attributo di tipo MainDate per l'archivio con ID {command.IdArchive}"); } ICollection <DocumentAttribute> preservationAttributes = archiveAttributes.Where(x => x.ConservationPosition > 0).ToList(); if (preservationAttributes.Count == 0) { _logger.Error($"There aren't conservation attributes for archive with Id {command.IdArchive}"); throw new Exception($"Non sono stati definiti gli attributi di conservazione per l'archivio con ID {command.IdArchive}"); } if (_preservationService.ExistPreservationsByArchive(currentArchive)) { _logger.Error($"The archive {command.IdArchive} already has some conservation done"); throw new Exception($"L'archivio {command.IdArchive} presenta già delle conservazioni eseguite"); } _logger.Info($"Enable archive {currentArchive.Name} to conservation"); await SendNotification(commandModel.ReferenceId, $"Abilitazione archivio {currentArchive.Name}({currentArchive.IdArchive}) alla conservazione", NotifyLevel.Info); currentArchive.IsLegal = true; ArchiveService.UpdateArchive(currentArchive, false); ICollection <Document> documents = DocumentService.GetDocumentsFromArchive(currentArchive); _logger.Debug($"Found {documents.Count} documents to process"); await SendNotification(commandModel.ReferenceId, $"Trovati {documents.Count} documenti da processare. L'attività può richiedere diversi minuti...", NotifyLevel.Info); BindingList <DocumentAttributeValue> documentAttributeValues; DateTime?mainDate; string primaryKey; decimal percentage, pulsePercentageLimit = 20; int progress = 1, totalItems = documents.Count, totalErrorDocuments = 0; ICollection <NotificationDetailModel> errorDetails = new List <NotificationDetailModel>(); foreach (Document document in documents) { try { _logger.Debug($"Process document {document.IdDocument}({progress} di {totalItems})"); documentAttributeValues = AttributeService.GetFullDocumentAttributeValues(document.IdDocument); mainDate = document.DateCreated; primaryKey = AttributeService.ParseAttributeValues(documentAttributeValues, archiveAttributes, out mainDate); DocumentService.UpdatePrimaryKeyAndDateMainDocument(document, mainDate, primaryKey); } catch (Exception ex) { _logger.Error($"Error on update document {document.IdDocument}", ex); errorDetails.Add(new NotificationDetailModel() { Id = document.IdDocument, ActivityName = $"Modifica primary key e maindate del documento {document.IdDocument}", Detail = $"{ex.Message}\r\n{ex.StackTrace}" }); totalErrorDocuments++; } percentage = ((decimal)progress / totalItems) * 100.0m; if (Math.Ceiling(percentage) > pulsePercentageLimit) { await SendNotification(commandModel.ReferenceId, $"Migrazione documenti ({pulsePercentageLimit}%, {totalErrorDocuments} in errore)", (totalErrorDocuments > 0 ? NotifyLevel.Warning : NotifyLevel.Info), errorDetails); pulsePercentageLimit += 20; } progress++; } await SendNotification(commandModel.ReferenceId, $"Migrazione documenti (100%, {totalErrorDocuments} in errore)", (totalErrorDocuments > 0 ? NotifyLevel.Warning : NotifyLevel.Info)); _logger.Info("Build Index and AwardBatch style files"); await SendNotification(commandModel.ReferenceId, "Creazione fogli di stile per visualizzazione file di Indice e Lotti", NotifyLevel.Info); string indexXsl = _preservationService.BuildPreservationIndexXSL(currentArchive); string awardBatchXsl = _preservationService.GetAwardBatchXSL(); ArchiveCompany archiveCompany = _preservationService.GetArchiveCompanies(currentArchive.IdArchive).SingleOrDefault(); if (archiveCompany == null) { archiveCompany = new ArchiveCompany() { IdArchive = currentArchive.IdArchive, IdCompany = currentCompany.IdCompany, WorkingDir = $@"{currentArchive.PathPreservation}\{currentArchive.Name}\Comunicazioni", XmlFileTemplatePath = $@"{currentArchive.PathPreservation}\{currentArchive.Name}\Comunicazioni\Template.xml" }; archiveCompany = ArchiveService.AddArchiveCompany(archiveCompany); } archiveCompany.AwardBatchXSLTFile = awardBatchXsl; archiveCompany.TemplateXSLTFile = indexXsl; ArchiveService.UpdateArchiveCompany(archiveCompany); StringBuilder resultBuilder = new StringBuilder(); resultBuilder.Append($"Archivio {currentArchive.Name} configurato correttamente per la conservazione"); if (totalErrorDocuments > 0) { resultBuilder.Append(". Alcuni documenti non sono stati migrati e potrebbero dare errore in fase di conservazione"); } await SendNotification(commandModel.ReferenceId, resultBuilder.ToString(), NotifyLevel.Info, true); } catch (Exception ex) { _logger.Error("Error on configure archive for preservation", ex); await SendNotification(commandModel.ReferenceId, $"Errore nella configurazione dell'archivio per la conservazione", NotifyLevel.Error, new List <NotificationDetailModel>() { new NotificationDetailModel() { Id = Guid.NewGuid(), ActivityName = $"Errore configurazione archivo", Detail = $"{ex.Message}\r\n{ex.StackTrace}" } }, true); } }