public async Task <BulkUploadResultViewModel> UploadFile(string userId, UploadApprenticeshipsViewModel uploadApprenticeshipsViewModel, SignInUserModel signInUser) { var commitmentId = HashingService.DecodeValue(uploadApprenticeshipsViewModel.HashedCommitmentId); var providerId = uploadApprenticeshipsViewModel.ProviderId; var fileName = uploadApprenticeshipsViewModel.Attachment?.FileName ?? "<unknown>"; var commitment = await GetCommitment(providerId, commitmentId); AssertCommitmentStatus(commitment); await AssertAutoReservationEnabled(commitment); Logger.Info($"Uploading File - Filename:{fileName}", uploadApprenticeshipsViewModel.ProviderId, commitmentId); var fileValidationResult = await _bulkUploader.ValidateFileStructure(uploadApprenticeshipsViewModel, providerId, commitment); if (fileValidationResult.Errors.Any()) { return(new BulkUploadResultViewModel { BulkUploadId = fileValidationResult.BulkUploadId, HasFileLevelErrors = true, FileLevelErrors = fileValidationResult.Errors }); } Logger.Info("Uploading file of apprentices.", providerId, commitmentId); var rowValidationResult = await _bulkUploader.ValidateFileRows(fileValidationResult.Data, providerId, fileValidationResult.BulkUploadId); var sw = Stopwatch.StartNew(); var overlapErrors = await GetOverlapErrors(fileValidationResult.Data.ToList()); Logger.Trace($"Validating overlaps took {sw.ElapsedMilliseconds}"); var rowErrors = rowValidationResult.Errors.ToList(); rowErrors.AddRange(overlapErrors); var hashedBulkUploadId = HashingService.HashValue(fileValidationResult.BulkUploadId); if (rowErrors.Any()) { Logger.Info($"{rowErrors.Count} Upload errors", providerId, commitmentId); return(new BulkUploadResultViewModel { BulkUploadId = fileValidationResult.BulkUploadId, BulkUploadReference = hashedBulkUploadId, HasRowLevelErrors = true, RowLevelErrors = rowErrors }); } try { await Mediator.Send(new BulkUploadApprenticeshipsCommand { UserId = userId, ProviderId = providerId, CommitmentId = commitmentId, Apprenticeships = await _mapper.MapFrom(commitmentId, rowValidationResult.Data), UserEmailAddress = signInUser.Email, UserDisplayName = signInUser.DisplayName }); } catch (Exception) { var overlaps = (await GetOverlapErrors(fileValidationResult.Data.ToList())).ToList(); if (overlaps.Any()) { return(new BulkUploadResultViewModel { BulkUploadId = fileValidationResult.BulkUploadId, HasRowLevelErrors = true, RowLevelErrors = overlaps }); } throw; } return(new BulkUploadResultViewModel { BulkUploadId = fileValidationResult.BulkUploadId }); }