示例#1
0
        public async Task <OrchestratorResponse <UpdateApprenticeshipViewModel> > GetConfirmChangesModel(
            string hashedAccountId, string hashedApprenticeshipId, string externalUserId,
            ApprenticeshipViewModel apprenticeship)
        {
            var accountId        = _hashingService.DecodeValue(hashedAccountId);
            var apprenticeshipId = _hashingService.DecodeValue(hashedApprenticeshipId);

            _logger.Debug($"Getting confirm change model: {accountId}, ApprenticeshipId: {apprenticeshipId}");

            return(await CheckUserAuthorization(async() =>
            {
                await AssertApprenticeshipStatus(accountId, apprenticeshipId);

                var data = await _mediator.SendAsync(new GetApprenticeshipQueryRequest
                {
                    AccountId = accountId,
                    ApprenticeshipId = apprenticeshipId
                });

                var apprenticeships = _apprenticeshipMapper.CompareAndMapToApprenticeshipViewModel(data.Apprenticeship,
                                                                                                   apprenticeship);

                return new OrchestratorResponse <UpdateApprenticeshipViewModel>
                {
                    Data = await apprenticeships
                };
            }, hashedAccountId, externalUserId));
        }
        public async Task ShouldUpdateTrainngProgramForStandard()
        {
            var a = new Apprenticeship
            {
                TrainingCode = "abba-666"
            };

            var updated = new ApprenticeshipViewModel
            {
                TrainingCode = "007"
            };

            MockMediator.Setup(m => m.SendAsync(It.IsAny <GetTrainingProgrammesQueryRequest>()))
            .ReturnsAsync(
                new GetTrainingProgrammesQueryResponse
            {
                TrainingProgrammes = new List <TrainingProgramme>
                {
                    new TrainingProgramme {
                        CourseCode = "abba-555", Name = "Framework Title"
                    },
                    new TrainingProgramme {
                        CourseCode = "007", Name = "Standard Title",
                    }
                }
            });

            var model = await Sut.CompareAndMapToApprenticeshipViewModel(a, updated);

            model.TrainingCode.Should().Be("007");
            model.TrainingName.Should().Be("Standard Title");
            model.TrainingType.Should().Be(TrainingType.Standard);
        }
示例#3
0
        public Dictionary <string, string> ValidateToDictionary(ApprenticeshipViewModel model)
        {
            var result = Validate(model);

            return(result.Errors.ToDictionary(
                       approvedError => approvedError.PropertyName, approvedError => approvedError.ErrorMessage));
        }
        public async Task GivenValidUlnAndAccountIdShouldCallServiceAndReturnApprenticeshipView()
        {
            ///Arrange
            var apprenticeshipHashId = "V673UHWE";
            var accountHashId        = "HTYDUD120";
            var apprenticeshipVm     = new ApprenticeshipViewModel
            {
                Uln = "123456782"
            };

            _orchestrator
            .Setup(x => x.GetApprenticeship(apprenticeshipHashId, accountHashId))
            .ReturnsAsync(apprenticeshipVm)
            .Verifiable();

            var controller = new ApprenticeshipsController(_orchestrator.Object);

            // Act
            var result = await controller.Index(apprenticeshipHashId, accountHashId);

            // Assert
            _orchestrator.VerifyAll();

            var view = result as ViewResult;

            view.Should().NotBeNull();
            view.Model.Should().BeOfType <ApprenticeshipViewModel>();
        }
        public Apprenticeship MapFrom(long commitmentId, ApprenticeshipViewModel viewModel, IList <TrainingProgramme> trainingProgrammes)
        {
            var apprenticeship = new Apprenticeship
            {
                CommitmentId = commitmentId,
                FirstName    = viewModel.FirstName,
                LastName     = viewModel.LastName,
                DateOfBirth  = viewModel.DateOfBirth.DateTime,
                NINumber     = viewModel.NINumber,
                ULN          = viewModel.ULN,
                Cost         = viewModel.Cost == null ? default(decimal?) : decimal.Parse(viewModel.Cost),
                StartDate    = viewModel.StartDate.DateTime,
                EndDate      = viewModel.EndDate.DateTime,
                ProviderRef  = viewModel.ProviderRef
            };

            if (!string.IsNullOrWhiteSpace(viewModel.CourseCode))
            {
                var training = trainingProgrammes.Single(x => x.CourseCode == viewModel.CourseCode);
                apprenticeship.TrainingType = int.TryParse(training.CourseCode, out _) ? ApiTrainingType.Standard : ApiTrainingType.Framework;
                apprenticeship.TrainingCode = viewModel.CourseCode;
                apprenticeship.TrainingName = training.Name;
            }

            return(apprenticeship);
        }
        public async Task <IDictionary <string, string> > ValidateApprenticeship(ApprenticeshipViewModel apprenticeship, UpdateApprenticeshipViewModel updatedModel)
        {
            ConcurrentDictionary <string, string> errors = new ConcurrentDictionary <string, string>();
            await Task.WhenAll(AddOverlapAndDateValidationErrors(errors, apprenticeship, updatedModel), AddReservationValidationErrors(errors, apprenticeship));

            return(errors);
        }
        public async Task ShouldUpdateTrainngProgramForStandard()
        {
            var a = new Apprenticeship
            {
                TrainingCode = "abba-666"
            };

            var updated = new ApprenticeshipViewModel
            {
                TrainingCode = "standard-007"
            };

            _mockMediator.Setup(m => m.SendAsync(It.IsAny <GetTrainingProgrammesQueryRequest>()))
            .ReturnsAsync(
                new GetTrainingProgrammesQueryResponse
            {
                TrainingProgrammes = new List <ITrainingProgramme>
                {
                    new Framework {
                        Id = "abba-555", FrameworkCode = 05, PathwayCode = 88, ProgrammeType = 2, Title = "Framework Title"
                    },
                    new Standard {
                        Id = "standard-007", Title = "Standard Title",
                    }
                }
            });

            var model = await _mappingTjänst.CompareAndMapToApprenticeshipViewModel(a, updated);

            model.TrainingCode.Should().Be("standard-007");
            model.TrainingName.Should().Be("Standard Title");
            model.TrainingType.Should().Be(TrainingType.Standard);
        }
示例#8
0
        public async Task <ActionResult> EditApprenticeship(ApprenticeshipViewModel apprenticeship)
        {
            if (!ModelState.IsValid)
            {
                apprenticeship.AddErrorsFromModelState(ModelState);
            }

            var validatorResult = await _employerCommitmentsOrchestrator.ValidateApprenticeship(apprenticeship);

            if (validatorResult.Any())
            {
                apprenticeship.AddErrorsFromDictionary(validatorResult);
            }

            if (apprenticeship.ErrorDictionary.Any())
            {
                return(await RedisplayEditApprenticeshipView(apprenticeship));
            }

            try
            {
                await _employerCommitmentsOrchestrator.UpdateApprenticeship(apprenticeship, OwinWrapper.GetClaimValue(@"sub"));
            }
            catch (InvalidRequestException ex)
            {
                apprenticeship.AddErrorsFromDictionary(ex.ErrorMessages);
                return(await RedisplayEditApprenticeshipView(apprenticeship));
            }

            return(RedirectToAction("Details", new { hashedAccountId = apprenticeship.HashedAccountId, hashedCommitmentId = apprenticeship.HashedCommitmentId }));
        }
        public async Task <ActionResult> ConfirmChanges(long providerId, ApprenticeshipViewModel model)
        {
            var updateViewModel = await _orchestrator.GetConfirmChangesModel(providerId, model.HashedApprenticeshipId, model);

            var validationErrors = await _orchestrator.ValidateEditApprenticeship(model, updateViewModel);

            foreach (var error in validationErrors)
            {
                if (ModelState.ContainsKey(error.Key))
                {
                    continue;
                }
                ModelState.AddModelError(error.Key, error.Value);
            }

            if (!ModelState.IsValid)
            {
                return(await RedisplayEditApprenticeshipView(model));
            }


            if (!AnyChanges(updateViewModel))
            {
                ModelState.AddModelError("NoChangesRequested", "No changes made");
                return(await RedisplayEditApprenticeshipView(model));
            }

            ModelState.Clear();
            return(View(updateViewModel));
        }
        public void BaseSetup()
        {
            MockMediator = new Mock <IMediator>();
            MockMediator.Setup(x => x.SendAsync(It.IsAny <GetTrainingProgrammesQueryRequest>()))
            .ReturnsAsync(new GetTrainingProgrammesQueryResponse
            {
                TrainingProgrammes = new List <TrainingProgramme>
                {
                    new TrainingProgramme
                    {
                        CourseCode    = "TESTCOURSE",
                        EffectiveFrom = new DateTime(2018, 5, 1),
                        EffectiveTo   = new DateTime(2018, 7, 1)
                    }
                }
            });

            YearNow = DateTime.Now.Year;
            CurrentDateTime.Setup(x => x.Now).Returns(DateTime.Now.AddMonths(6));
            var academicYearProvider = new AcademicYearDateProvider(CurrentDateTime.Object);

            Validator = new ApprenticeshipViewModelValidator(
                new WebApprenticeshipValidationText(academicYearProvider),
                academicYearProvider,
                new AcademicYearValidator(CurrentDateTime.Object, academicYearProvider),
                CurrentDateTime.Object,
                MockMediator.Object);

            ValidModel = new ApprenticeshipViewModel
            {
                ULN       = "1001234567",
                FirstName = "TestFirstName",
                LastName  = "TestLastName"
            };
        }
示例#11
0
        public async Task <Dictionary <string, string> > ValidateApprenticeship(ApprenticeshipViewModel viewModel)
        {
            var overlappingErrors = await Mediator.Send(
                new GetOverlappingApprenticeshipsQueryRequest
            {
                Apprenticeship = new List <Apprenticeship> {
                    await _apprenticeshipMapper.MapApprenticeship(viewModel)
                }
            });

            var result = _apprenticeshipCoreValidator.MapOverlappingErrors(overlappingErrors);

            // EndDate is optional before approval
            if (viewModel.EndDate.DateTime != null)
            {
                var endDateError = _apprenticeshipCoreValidator.CheckEndDateInFuture(viewModel.EndDate);
                if (endDateError != null)
                {
                    result.AddIfNotExists(endDateError.Value);
                }
            }

            var uniqueUlnValidationResult = await _uniqueUlnValidator.ValidateAsyncOverride(viewModel);

            if (!uniqueUlnValidationResult.IsValid)
            {
                foreach (var error in uniqueUlnValidationResult.Errors)
                {
                    result.AddIfNotExists(error.PropertyName, error.ErrorMessage);
                }
            }

            return(result);
        }
        private async Task <ActionResult> RedisplayEditApprenticeshipView(ApprenticeshipViewModel apprenticeship)
        {
            var viewModel = await _orchestrator.GetApprenticeshipForEdit(apprenticeship.ProviderId, apprenticeship.HashedApprenticeshipId);

            ViewBag.ApprenticeshipProgrammes = viewModel.ApprenticeshipProgrammes;
            return(View("Edit", apprenticeship));
        }
        public async Task ThenIfTheUlnIsNotUniqueThenNotValid()
        {
            //Arrange
            var viewModel = new ApprenticeshipViewModel
            {
                ULN = "TEST"
            };

            _mediator.Setup(x => x.Send(It.IsAny <GetCommitmentQueryRequest>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(() => new GetCommitmentQueryResponse
            {
                Commitment = new CommitmentView
                {
                    Apprenticeships = new List <Apprenticeship>
                    {
                        new Apprenticeship {
                            Id = 1, ULN = "TEST2"
                        },
                        new Apprenticeship {
                            Id = 2, ULN = "TEST"
                        },
                        new Apprenticeship {
                            Id = 3, ULN = "TEST3"
                        }
                    }
                }
            });

            //Act
            var result = await _validator.ValidateAsync(viewModel);

            //Assert
            Assert.IsFalse(result.IsValid);
        }
示例#14
0
        public async Task ShouldCallReservationValidationsAndReturnErrors()
        {
            var viewModel = new ApprenticeshipViewModel();

            viewModel.ReservationId = Guid.NewGuid();
            viewModel.StartDate     = new DateTimeViewModel(1, 1, 2001);

            var updateModel = new UpdateApprenticeshipViewModel();

            MockMediator.Setup(m => m.SendAsync(It.IsAny <GetReservationValidationRequest>()))
            .ReturnsAsync(new GetReservationValidationResponse
            {
                Data = new ReservationValidationResult(new List <ReservationValidationError>
                {
                    new ReservationValidationError("Reservation", "A reservation issue")
                })
            });

            var result = await Orchestrator.ValidateApprenticeship(viewModel, updateModel);

            Assert.IsTrue(result.ContainsKey("Reservation"));
            Assert.AreEqual("A reservation issue", result["Reservation"]);

            MockMediator.Verify(m => m.SendAsync(It.IsAny <GetReservationValidationRequest>()), Times.Once);
        }
        public async Task ShouldNotUpdateDatesIfNotChanged()
        {
            var a = new Apprenticeship
            {
                DateOfBirth = new DateTime(1998, 12, 8),
                StartDate   = new DateTime(2045, 12, 08),
                EndDate     = new DateTime(2046, 12, 08)
            };

            var dob     = new DateTimeViewModel(8, 12, 1998);
            var sd      = new DateTimeViewModel(08, 12, 2045);
            var ed      = new DateTimeViewModel(08, 12, 2046);
            var updated = new ApprenticeshipViewModel
            {
                DateOfBirth = dob,
                StartDate   = sd,
                EndDate     = ed
            };

            var model = await Sut.CompareAndMapToApprenticeshipViewModel(a, updated);

            model.DateOfBirth.Should().BeNull();
            model.StartDate.Should().BeNull();
            model.EndDate.Should().BeNull();
        }
        public async Task UpdateEveryField()
        {
            var a = new Apprenticeship
            {
                FirstName   = "Kalle",
                LastName    = "Abba",
                EmployerRef = "This is a reference",
                Cost        = 4.0M
            };

            var updated = new ApprenticeshipViewModel
            {
                FirstName   = "Fredrik",
                LastName    = "Stockborg",
                EmployerRef = "New ref",
                Cost        = "5"
            };

            var model = await Sut.CompareAndMapToApprenticeshipViewModel(a, updated);

            model.FirstName.Should().Be("Fredrik");
            model.LastName.Should().Be("Stockborg");
            model.EmployerRef.Should().Be("New ref");
            model.Cost.Should().Be("5");
        }
        public async Task ShouldValidate()
        {
            var viewModel   = new ApprenticeshipViewModel();
            var updateModel = new CreateApprenticeshipUpdateViewModel();

            _mockMapper
            .Setup(m => m.MapApprenticeship(It.IsAny <ApprenticeshipViewModel>()))
            .ReturnsAsync(new Apprenticeship {
                ReservationId = Guid.NewGuid(), StartDate = DateTime.Today
            });

            _mockMediator
            .Setup(m => m.Send(It.IsAny <GetOverlappingApprenticeshipsQueryRequest>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new GetOverlappingApprenticeshipsQueryResponse {
                Overlaps = new List <ApprenticeshipOverlapValidationResult>()
            });

            _mockMediator
            .Setup(m => m.Send(It.IsAny <GetReservationValidationRequest>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new GetReservationValidationResponse {
                Data = new ReservationValidationResult(new ReservationValidationError[0])
            });

            await _orchestrator.ValidateEditApprenticeship(viewModel, updateModel);

            _mockMediator.Verify(m => m.Send(It.IsAny <GetOverlappingApprenticeshipsQueryRequest>(), It.IsAny <CancellationToken>()), Times.Once, failMessage: "Should call");
            _mockMediator.Verify(m => m.Send(It.IsAny <GetReservationValidationRequest>(), It.IsAny <CancellationToken>()), Times.Once, failMessage: "Should call");
            _mockValidator.Verify(m => m.MapOverlappingErrors(It.IsAny <GetOverlappingApprenticeshipsQueryResponse>()), Times.Once, failMessage: "Should verify overlapping apprenticeship");
            _mockValidator.Verify(m => m.ValidateToDictionary(It.IsAny <ApprenticeshipViewModel>()), Times.Once, failMessage: "Should validate apprenticeship");
            _mockValidator.Verify(m => m.ValidateAcademicYear(It.IsAny <CreateApprenticeshipUpdateViewModel>()), Times.Once, failMessage: "Should validate academic year");
        }
        private ApprenticeshipUploadModel MapTo(CsvRecord record, CommitmentView commitment)
        {
            var dateOfBirth      = GetValidDate(record.DateOfBirth, "yyyy-MM-dd");
            var learnerStartDate = GetValidDate(record.StartDate, "yyyy-MM");
            var learnerEndDate   = GetValidDate(record.EndDate, "yyyy-MM");

            var courseCode = record.ProgType == "25"
                                   ? record.StdCode
                                   : $"{record.FworkCode}-{record.ProgType}-{record.PwayCode}";

            var apprenticeshipViewModel = new ApprenticeshipViewModel
            {
                AgreementStatus     = AgreementStatus.NotAgreed,
                PaymentStatus       = PaymentStatus.Active,
                ULN                 = record.ULN,
                FirstName           = record.GivenNames,
                LastName            = record.FamilyName,
                DateOfBirth         = new DateTimeViewModel(dateOfBirth),
                Cost                = record.TotalPrice,
                ProviderRef         = record.ProviderRef,
                StartDate           = new DateTimeViewModel(learnerStartDate),
                EndDate             = new DateTimeViewModel(learnerEndDate),
                ProgType            = record.ProgType.TryParse(),
                CourseCode          = courseCode,
                IsPaidForByTransfer = commitment.IsTransfer()
            };

            return(new ApprenticeshipUploadModel
            {
                ApprenticeshipViewModel = apprenticeshipViewModel,
                CsvRecord = record
            });
        }
示例#19
0
        public async Task <Apprenticeship> MapFrom(ApprenticeshipViewModel viewModel)
        {
            var apprenticeship = new Apprenticeship
            {
                CommitmentId = _hashingService.DecodeValue(viewModel.HashedCommitmentId),
                Id           = string.IsNullOrWhiteSpace(viewModel.HashedApprenticeshipId) ? 0L : _hashingService.DecodeValue(viewModel.HashedApprenticeshipId),
                FirstName    = viewModel.FirstName,
                LastName     = viewModel.LastName,
                DateOfBirth  = viewModel.DateOfBirth.DateTime,
                NINumber     = viewModel.NINumber,
                ULN          = viewModel.ULN,
                Cost         = viewModel.Cost.AsNullableDecimal(),
                StartDate    = viewModel.StartDate.DateTime,
                EndDate      = viewModel.EndDate.DateTime,
                ProviderRef  = viewModel.ProviderRef,
                EmployerRef  = viewModel.EmployerRef
            };

            if (!string.IsNullOrWhiteSpace(viewModel.TrainingCode))
            {
                var training = await GetTrainingProgramme(viewModel.TrainingCode);

                apprenticeship.TrainingType = training is Standard ? TrainingType.Standard : TrainingType.Framework;
                apprenticeship.TrainingCode = viewModel.TrainingCode;
                apprenticeship.TrainingName = training.Title;
            }

            return(apprenticeship);
        }
        public async Task ShouldUpdateDate()
        {
            var a = new Apprenticeship
            {
                DateOfBirth = new DateTime(1990, 11, 11),
                StartDate   = new DateTime(2045, 12, 08),
                EndDate     = new DateTime(2046, 12, 08)
            };

            var dob     = new DateTimeViewModel(8, 12, 1998);
            var sd      = new DateTimeViewModel(08, 5, 2044);
            var ed      = new DateTimeViewModel(09, 12, 2047);
            var updated = new ApprenticeshipViewModel
            {
                DateOfBirth = dob,
                StartDate   = sd,
                EndDate     = ed
            };

            var model = await Sut.CompareAndMapToApprenticeshipViewModel(a, updated);

            model.DateOfBirth.Should().Be(dob);
            model.StartDate.Should().Be(sd);
            model.EndDate.Should().Be(ed);
        }
        public void BaseSetup()
        {
            CurrentDateTime.Setup(x => x.Now).Returns(new DateTime(2018, 5, 1));

            Validator = new ApprenticeshipViewModelValidator(new WebApprenticeshipValidationText(), CurrentDateTime.Object, new AcademicYear(CurrentDateTime.Object));

            ValidModel = new ApprenticeshipViewModel {
                ULN = "1001234567", FirstName = "TestFirstName", LastName = "TestLastName"
            };
        }
示例#22
0
        public async Task ThenEndDateShouldntBeValidatedIfNotSupplied()
        {
            var apprenticeship = new ApprenticeshipViewModel {
                EndDate = new DateTimeViewModel()
            };

            var result = await _orchestrator.ValidateApprenticeship(apprenticeship);

            CollectionAssert.AreEqual(new Dictionary <string, string>(), result);
        }
        public async Task ThenValidationIsNotPerformedOnAnEmptyUln()
        {
            //Arrange
            var viewModel = new ApprenticeshipViewModel();

            //Act
            await _validator.ValidateAsync(viewModel);

            //Assert
            _mediator.Verify(x => x.Send(It.IsAny <GetCommitmentQueryRequest>(), It.IsAny <CancellationToken>()), Times.Never);
        }
        public async Task ShouldAppendErrorsTogether()
        {
            var viewModel   = new ApprenticeshipViewModel();
            var updateModel = new CreateApprenticeshipUpdateViewModel();

            _mockMapper
            .Setup(m => m.MapApprenticeship(It.IsAny <ApprenticeshipViewModel>()))
            .ReturnsAsync(new Apprenticeship {
                ReservationId = Guid.NewGuid(), StartDate = DateTime.Today
            });

            _mockMediator
            .Setup(m => m.Send(It.IsAny <GetOverlappingApprenticeshipsQueryRequest>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new GetOverlappingApprenticeshipsQueryResponse {
                Overlaps = new List <ApprenticeshipOverlapValidationResult>()
            });

            _mockValidator
            .Setup(v => v.ValidateToDictionary(viewModel))
            .Returns(BuildDictionary("VTD1=error1", "VTD2=error2"));

            _mockValidator
            .Setup(v => v.ValidateAcademicYear(updateModel))
            .Returns(BuildDictionary("VAY1=error3", "VAY2=error4"));

            _mockValidator
            .Setup(v => v.MapOverlappingErrors(It.IsAny <GetOverlappingApprenticeshipsQueryResponse>()))
            .Returns(BuildDictionary("OLE1=error7", "OLE2=error8"));

            _mockMediator
            .Setup(m => m.Send(It.IsAny <GetReservationValidationRequest>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new GetReservationValidationResponse
            {
                Data = new ReservationValidationResult(new[]
                {
                    new ReservationValidationError("RVE1", "error9"),
                    new ReservationValidationError("RVE2", "error10")
                })
            });

            var errors = await _orchestrator.ValidateEditApprenticeship(viewModel, updateModel);

            TickoffError(errors, "VTD1", "error1");
            TickoffError(errors, "VTD2", "error2");
            TickoffError(errors, "VAY1", "error3");
            TickoffError(errors, "VAY2", "error4");
            TickoffError(errors, "OLE1", "error7");
            TickoffError(errors, "OLE2", "error8");
            TickoffError(errors, "RVE1", "error9");
            TickoffError(errors, "RVE2", "error10");

            Assert.AreEqual(0, errors.Count, "Additional unexpected errors were returned by the validator");
        }
示例#25
0
        public Dictionary <string, string> ValidateAcademicYear(ApprenticeshipViewModel model)
        {
            var dict = new Dictionary <string, string>();

            if (model.StartDate?.DateTime != null &&
                _academicYearValidator.Validate(model.StartDate.DateTime.Value) == AcademicYearValidationResult.NotWithinFundingPeriod)
            {
                dict.Add($"{nameof(model.StartDate)}", ValidationText.AcademicYearStartDate01.Text);
            }

            return(dict);
        }
示例#26
0
        public async Task ShouldValidateOverlapAndDateChecks()
        {
            var viewModel   = new ApprenticeshipViewModel();
            var updateModel = new UpdateApprenticeshipViewModel();


            await Orchestrator.ValidateApprenticeship(viewModel, updateModel);

            MockMediator.Verify(m => m.SendAsync(It.IsAny <GetOverlappingApprenticeshipsQueryRequest>()), Times.Once, failMessage: "Should call");
            _mockValidator.Verify(m => m.MapOverlappingErrors(It.IsAny <GetOverlappingApprenticeshipsQueryResponse>()), Times.Once, failMessage: "Should verify overlapping apprenticeship");
            _mockValidator.Verify(m => m.ValidateToDictionary(It.IsAny <ApprenticeshipViewModel>()), Times.Once, failMessage: "Should validate apprenticeship");
            _mockValidator.Verify(m => m.ValidateAcademicYear(It.IsAny <UpdateApprenticeshipViewModel>()), Times.Once, failMessage: "Should validate academic year");
        }
        public async Task ThenEndDateShouldntBeValidatedIfNotSupplied()
        {
            MockApprenticeshipCoreValidator.Setup(v => v.MapOverlappingErrors(It.IsAny <GetOverlappingApprenticeshipsQueryResponse>()))
            .Returns(new Dictionary <string, string>());

            var apprenticeship = new ApprenticeshipViewModel {
                EndDate = new DateTimeViewModel()
            };

            var result = await EmployerCommitmentOrchestrator.ValidateApprenticeship(apprenticeship);

            CollectionAssert.AreEqual(new Dictionary <string, string>(), result);
        }
        public async Task ShouldMapHasHadDataLockSuccess(bool expectedHasHadDataLockSuccess, bool hasHadDataLockSuccess)
        {
            var apprenticeship = new Apprenticeship
            {
                HasHadDataLockSuccess = hasHadDataLockSuccess
            };

            var updated = new ApprenticeshipViewModel();

            var model = await Sut.CompareAndMapToApprenticeshipViewModel(apprenticeship, updated);

            model.HasHadDataLockSuccess.Should().Be(expectedHasHadDataLockSuccess);
        }
        public async Task <ActionResult> ConfirmChanges(ApprenticeshipViewModel apprenticeship)
        {
            if (!await IsUserRoleAuthorized(apprenticeship.HashedAccountId, Role.Owner, Role.Transactor))
            {
                return(View("AccessDenied"));
            }

            if (!ModelState.IsValid)
            {
                apprenticeship.AddErrorsFromModelState(ModelState);
            }

            var model = await _orchestrator.GetConfirmChangesModel(
                apprenticeship.HashedAccountId,
                apprenticeship.HashedApprenticeshipId,
                OwinWrapper.GetClaimValue(@"sub"),
                apprenticeship);

            var validatorResult = await _orchestrator.ValidateApprenticeship(apprenticeship, model.Data);

            if (validatorResult.Any())
            {
                apprenticeship.AddErrorsFromDictionary(validatorResult);
            }

            if (apprenticeship.ErrorDictionary.Any())
            {
                var viewModel = await _orchestrator.GetApprenticeshipForEdit(apprenticeship.HashedAccountId, apprenticeship.HashedApprenticeshipId, OwinWrapper.GetClaimValue(@"sub"));

                viewModel.Data.Apprenticeship = apprenticeship;
                SetErrorMessage(viewModel, viewModel.Data.Apprenticeship.ErrorDictionary);

                return(View("Edit", viewModel));
            }

            if (!AnyChanges(model.Data))
            {
                var viewModel = await _orchestrator.GetApprenticeshipForEdit(apprenticeship.HashedAccountId, apprenticeship.HashedApprenticeshipId, OwinWrapper.GetClaimValue(@"sub"));

                viewModel.Data.Apprenticeship = apprenticeship;
                viewModel.Data.Apprenticeship.ErrorDictionary.Add("NoChangesRequested", "No changes made");

                SetErrorMessage(viewModel, viewModel.Data.Apprenticeship.ErrorDictionary);

                return(View("Edit", viewModel));
            }

            _orchestrator.CreateApprenticeshipViewModelCookie(model.Data);

            return(RedirectToAction("ConfirmChanges"));
        }
        public async Task <UpdateApprenticeshipViewModel> CompareAndMapToApprenticeshipViewModel(
            Apprenticeship original, ApprenticeshipViewModel edited)
        {
            string ChangedOrNull(string a, string edit) => a?.Trim() == edit?.Trim() ? null : edit;

            var apprenticeshipDetailsViewModel = MapToApprenticeshipDetailsViewModel(original);
            var model = new UpdateApprenticeshipViewModel
            {
                FirstName   = ChangedOrNull(original.FirstName, edited.FirstName),
                LastName    = ChangedOrNull(original.LastName, edited.LastName),
                DateOfBirth = original.DateOfBirth == edited.DateOfBirth.DateTime
                    ? null
                    : edited.DateOfBirth,
                Cost      = original.Cost == edited.Cost.AsNullableDecimal() ? null : edited.Cost,
                StartDate = original.StartDate == edited.StartDate.DateTime
                  ? null
                  : edited.StartDate,
                EndDate = original.EndDate == edited.EndDate.DateTime
                    ? null
                    : edited.EndDate,
                EmployerRef = original.EmployerRef?.Trim() == edited.EmployerRef?.Trim() ||
                              (string.IsNullOrEmpty(original.EmployerRef) && string.IsNullOrEmpty(edited.EmployerRef))
                    ? null
                    : edited.EmployerRef ?? "",
                OriginalApprenticeship = apprenticeshipDetailsViewModel
            };

            if (!string.IsNullOrWhiteSpace(edited.TrainingCode) && original.TrainingCode != edited.TrainingCode)
            {
                var training = await GetTrainingProgramme(edited.TrainingCode);

                if (training != null)
                {
                    model.TrainingType = int.TryParse(training.CourseCode, out _) ? TrainingType.Standard : TrainingType.Framework;
                    model.TrainingCode = edited.TrainingCode;
                    model.TrainingName = training.Name;
                }
                else
                {
                    model.TrainingType = edited.TrainingType;
                    model.TrainingCode = edited.TrainingCode;
                    model.TrainingName = edited.TrainingName;

                    _logger.Warn($"Apprentice training course has expired. TrainingName: {edited.TrainingName}, TrainingCode: {edited.TrainingCode}, Employer Ref: {edited.EmployerRef}, Apprenticeship ULN: {edited.ULN}");
                }
            }

            model.HasHadDataLockSuccess = original.HasHadDataLockSuccess;

            return(model);
        }