private async Task CleanTestData(Notification notification, PerformContext context, int runId)
        {
            var missingDateResults = notification.TestData.ManualTestResults
                                     .Where(result => !result.TestDate.HasValue)
                                     .ToList();

            foreach (var result in missingDateResults)
            {
                const string missingDateMessage = "had test results without a date set. " +
                                                  "The notification will be imported without this test record.";
                await _logger.LogNotificationWarning(context, runId, notification.LegacyId, missingDateMessage);

                notification.TestData.ManualTestResults.Remove(result);
            }

            var dateInFutureResults = notification.TestData.ManualTestResults
                                      .Where(result => result.TestDate > DateTime.Today)
                                      .ToList();

            foreach (var result in dateInFutureResults)
            {
                const string dateInFutureMessage = "had test results with date set in future. " +
                                                   "The notification will be imported without this test record.";
                await _logger.LogNotificationWarning(context, runId, notification.LegacyId, dateInFutureMessage);

                notification.TestData.ManualTestResults.Remove(result);
            }

            var missingResults = notification.TestData.ManualTestResults
                                 .Where(result => result.Result == null)
                                 .ToList();

            foreach (var result in missingResults)
            {
                const string missingResultMessage = "had test results without a result recorded. " +
                                                    "The notification will be imported without this test record.";
                await _logger.LogNotificationWarning(context, runId, notification.LegacyId, missingResultMessage);

                notification.TestData.ManualTestResults.Remove(result);
            }

            // After filtering out invalid tests, we might have none left
            if (!notification.TestData.ManualTestResults.Any())
            {
                notification.TestData.HasTestCarriedOut = false;
            }
        }
        private async Task <ImportResult> ValidateAndImportNotificationGroupAsync(PerformContext context, int runId,
                                                                                  List <Notification> notifications)
        {
            var importResult = new ImportResult(notifications.First().PatientDetails.FullName);

            _logger.LogInformation(context, runId,
                                   $"{notifications.Count} notifications found to import in notification group containing legacy ID {notifications.First().LegacyId}");

            // Verify that no repeated NotificationIds have returned
            var ids = notifications.Select(n => n.LegacyId).ToList();

            if (ids.Distinct().Count() != ids.Count)
            {
                importResult.AddGroupError("Aborting group import due to duplicate records found");
                await _logger.LogImportGroupFailure(context, runId, notifications, "due to duplicate records found");

                return(importResult);
            }

            var hasAnyRecordAlreadyBeenImported = false;

            foreach (var notification in notifications)
            {
                // Check that record hasn't already been imported
                var foundLtbr = notification.LTBRID is null
                    ? false
                    : await _notificationRepository.NotificationWithLegacyIdExistsAsync(notification.LTBRID);

                var foundEts = notification.ETSID is null
                    ? false
                    : await _notificationRepository.NotificationWithLegacyIdExistsAsync(notification.ETSID);

                if (foundEts || foundLtbr)
                {
                    hasAnyRecordAlreadyBeenImported = true;
                    var errorId      = foundLtbr ? $"LTBRId = {notification.LTBRID}" : $"ETSId = {notification.ETSID}";
                    var errorMessage = $"A notification has already been imported with {errorId}. " +
                                       "Please contact your system administrator to fix this issue.";
                    importResult.AddNotificationError(notification.LegacyId, errorMessage);
                }
            }

            if (hasAnyRecordAlreadyBeenImported)
            {
                await _logger.LogImportGroupFailure(context, runId, notifications, "due to notification having already been imported");

                return(importResult);
            }

            var isAnyNotificationInvalid = false;

            foreach (var notification in notifications)
            {
                var linkedNotificationId = notification.LegacyId;
                _logger.LogInformation(context, runId, $"Validating notification with Id={linkedNotificationId}");

                var validationErrors = await _importValidator.CleanAndValidateNotification(context,
                                                                                           runId,
                                                                                           notification);

                if (!validationErrors.Any())
                {
                    _logger.LogInformation(context, runId, "No validation errors found");
                    importResult.AddValidNotification(linkedNotificationId);
                }
                else
                {
                    isAnyNotificationInvalid = true;
                    importResult.AddValidationErrorsMessages(linkedNotificationId, validationErrors);
                    await _logger.LogNotificationWarning(context, runId, linkedNotificationId,
                                                         $"has {validationErrors.Count} validation errors");

                    foreach (var validationError in validationErrors)
                    {
                        await _logger.LogNotificationWarning(context, runId, linkedNotificationId, validationError.ErrorMessage);
                    }
                }
            }

            if (isAnyNotificationInvalid)
            {
                await _logger.LogImportGroupFailure(context, runId, notifications, "due to validation errors");

                return(importResult);
            }

            _logger.LogSuccess(context, runId, $"Importing {notifications.Count} valid notifications");

            var savedNotifications = await SaveLinkedNotifications(context, runId, importResult, notifications);

            if (savedNotifications != null &&
                await MarkNotificationsAsImported(context, runId, importResult, savedNotifications))
            {
                importResult.NtbsIds = savedNotifications.ToDictionary(x => x.LegacyId, x => x.NotificationId);
                await ImportLabResults(context, runId, importResult, savedNotifications);
                await MigrateCultureResistanceSummaries(context, runId, savedNotifications);
                await UpdateDrugResistanceProfiles(context, runId, savedNotifications);
                await UpdateClusterInformation(context, runId, savedNotifications);

                await _logger.LogGroupSuccess(context, runId, notifications);
            }

            return(importResult);
        }