public async Task <Unit> Handle(CertificateReprintRequest request, CancellationToken cancellationToken)
        {
            var certificate = await _certificateRepository.GetCertificate(request.CertificateReference, request.LastName, request.AchievementDate);

            if (certificate == null)
            {
                throw new NotFound();
            }

            if (certificate.Status == SFA.DAS.AssessorService.Domain.Consts.CertificateStatus.Reprint)
            {
                return(Unit.Value);
            }

            if (certificate.Status == SFA.DAS.AssessorService.Domain.Consts.CertificateStatus.Printed)
            {
                certificate.Status = SFA.DAS.AssessorService.Domain.Consts.CertificateStatus.Reprint;
                await _certificateRepository.Update(certificate, request.Username,
                                                    SFA.DAS.AssessorService.Domain.Consts.CertificateActions.Reprint);
            }
            else
            {
                throw new NotFound();
            }
            return(Unit.Value);
        }
Example #2
0
        private X509Certificate2 RetrieveCertificate(Signing signInfo)
        {
            if (signInfo.SigningCertificateInformation == null)
            {
                throw new ConfigurationErrorsException(
                          "No signing certificate information found in PMode to perform signing. "
                          + "Please provide either a <CertificateFindCriteria/> or <PrivateKeyCertificate/> tag to the Security.Signing element");
            }

            if (signInfo.SigningCertificateInformation is CertificateFindCriteria certFindCriteria)
            {
                return(_repository.GetCertificate(
                           findType: certFindCriteria.CertificateFindType,
                           privateKeyReference: certFindCriteria.CertificateFindValue));
            }

            if (signInfo.SigningCertificateInformation is PrivateKeyCertificate embeddedCertInfo)
            {
                return(new X509Certificate2(
                           rawData: Convert.FromBase64String(embeddedCertInfo.Certificate),
                           password: embeddedCertInfo.Password,
                           keyStorageFlags:
                           X509KeyStorageFlags.Exportable
                           | X509KeyStorageFlags.MachineKeySet
                           | X509KeyStorageFlags.PersistKeySet));
            }

            throw new NotSupportedException(
                      "The signing certificate information specified in the PMode could not be used to retrieve the certificate. " +
                      "Please provide either a <CertificateFindCriteria/> or <PrivateKeyCertificate/> tag to the Security.Signing element");
        }
        private X509Certificate2 GetCertificate(MessagingContext messagingContext)
        {
            Decryption decryption = messagingContext.ReceivingPMode.Security.Decryption;

            if (decryption.DecryptCertificateInformation == null)
            {
                throw new ConfigurationErrorsException(
                          "Cannot start decrypting: no certificate information found " +
                          $"in ReceivingPMode {messagingContext.ReceivingPMode.Id} to decrypt the message. " +
                          "Please use either a <CertificateFindCriteria/> or <PrivateKeyCertificate/> to specify the certificate information");
            }

            if (decryption.DecryptCertificateInformation is CertificateFindCriteria certFindCriteria)
            {
                return(_certificateRepository.GetCertificate(
                           certFindCriteria.CertificateFindType,
                           certFindCriteria.CertificateFindValue));
            }

            if (decryption.DecryptCertificateInformation is PrivateKeyCertificate embeddedCertInfo)
            {
                return(new X509Certificate2(
                           rawData: Convert.FromBase64String(embeddedCertInfo.Certificate),
                           password: embeddedCertInfo.Password,
                           keyStorageFlags: X509KeyStorageFlags.Exportable
                           | X509KeyStorageFlags.MachineKeySet
                           | X509KeyStorageFlags.PersistKeySet));
            }

            throw new NotSupportedException(
                      "The decrypt-certificate information specified in the ReceivingPMode " +
                      $"{messagingContext.ReceivingPMode.Id} could not be used to retrieve the certificate used for decryption. " +
                      "Please use either a <CertificateFindCriteria/> or <PrivateKeyCertificate/> to specify the certificate information");
        }
        public async Task <Unit> Handle(UpdateCertificateWithReprintReasonCommand request, CancellationToken cancellationToken)
        {
            var certificate = await _certificateRepository.GetCertificate(request.CertificateReference);

            if (certificate == null)
            {
                throw new NotFoundException();
            }

            try
            {
                var certificateData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);
                certificateData.ReprintReasons = ReprintReasonsToList(request.Reasons);
                certificateData.IncidentNumber = request.IncidentNumber;
                certificate.CertificateData    = JsonConvert.SerializeObject(certificateData);

                await _certificateRepository.Update(certificate, request.Username, CertificateActions.ReprintReason, true, request.OtherReason);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Unable to update certificate {request.CertificateReference} with reprint reason");
                throw;
            }

            return(Unit.Value);
        }
        public CreateBatchCertificateRequestValidator(
            IStringLocalizer <BatchCertificateRequestValidator> localiser,
            IOrganisationQueryRepository organisationQueryRepository,
            IIlrRepository ilrRepository,
            ICertificateRepository certificateRepository,
            IStandardService standardService)
        {
            Include(new BatchCertificateRequestValidator(localiser, organisationQueryRepository, ilrRepository, standardService));

            RuleFor(m => m.CertificateReference).Empty().WithMessage("Certificate reference must be empty").DependentRules(() =>
            {
                RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                {
                    var existingCertificate = await certificateRepository.GetCertificate(m.Uln, m.StandardCode);
                    var sumbittingEpao      = await organisationQueryRepository.GetByUkPrn(m.UkPrn);
                    var learnerDetails      = await ilrRepository.Get(m.Uln, m.StandardId.GetValueOrDefault());

                    if (existingCertificate != null && existingCertificate.Status != CertificateStatus.Deleted)
                    {
                        if (sumbittingEpao?.Id != existingCertificate.OrganisationId)
                        {
                            context.AddFailure(new ValidationFailure("CertificateData", $"Your organisation is not the creator of the EPA"));
                        }
                        else if (existingCertificate.Status == CertificateStatus.Draft)
                        {
                            var certData = JsonConvert.DeserializeObject <CertificateData>(existingCertificate.CertificateData);

                            if (!string.IsNullOrEmpty(certData.OverallGrade) && certData.AchievementDate.HasValue && !string.IsNullOrEmpty(certData.ContactPostCode))
                            {
                                context.AddFailure(new ValidationFailure("CertificateData", $"Certificate already exists: {existingCertificate.CertificateReference}"));
                            }
                            else if (!EpaOutcome.Pass.Equals(certData.EpaDetails?.LatestEpaOutcome, StringComparison.InvariantCultureIgnoreCase))
                            {
                                context.AddFailure(new ValidationFailure("CertificateData", $"Latest EPA Outcome has not passed"));
                            }
                        }
                        else
                        {
                            context.AddFailure(new ValidationFailure("CertificateData", $"Certificate already exists: {existingCertificate.CertificateReference}"));
                        }
                    }

                    if (learnerDetails != null)
                    {
                        if (learnerDetails.CompletionStatus == (int)CompletionStatus.Withdrawn)
                        {
                            context.AddFailure(new ValidationFailure("LearnerDetails", "Cannot find the apprentice details"));
                        }
                        else if (learnerDetails.CompletionStatus == (int)CompletionStatus.TemporarilyWithdrawn)
                        {
                            context.AddFailure(new ValidationFailure("LearnerDetails", "Cannot find the apprentice details"));
                        }
                    }
                    else
                    {
                        context.AddFailure(new ValidationFailure("LearnerDetails", $"Learner details for ULN: {m.Uln} not found"));
                    }
                });
            });
        }
        private async Task <Certificate> UpdateCertificate(UpdateBatchCertificateRequest request)
        {
            _logger.LogInformation("UpdateCertificate Before Get Standard from API");
            var standard = await _standardService.GetStandard(request.StandardCode);

            _logger.LogInformation("UpdateCertificate Before Get Certificate from db");
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (standard != null && certificate != null)
            {
                var certData = CombineCertificateData(JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData), request.CertificateData, standard);

                _logger.LogInformation("UpdateCertificate Before Update CertificateData");

                // need to update EPA Reference too
                certData.EpaDetails.EpaReference = certificate.CertificateReference;
                certificate.CertificateData      = JsonConvert.SerializeObject(certData);

                // adjust Status appropriately
                if (certificate.Status == CertificateStatus.Deleted)
                {
                    certificate.Status = CertificateStatus.Draft;
                }

                _logger.LogInformation("UpdateCertificate Before Update Cert in db");
                await _certificateRepository.Update(certificate, ExternalApiConstants.ApiUserName, CertificateActions.Amend);

                return(await CertificateHelpers.ApplyStatusInformation(_certificateRepository, _contactQueryRepository, certificate));
            }
            else
            {
                _logger.LogWarning($"UpdateCertificate Did not find Certificate for Uln {request.Uln} and StandardCode {request.StandardCode}");
                throw new NotFound();
            }
        }
        private X509Certificate2 RetrieveCertificate(SendingProcessingMode pmode)
        {
            Encryption encryptionSettings = pmode.Security.Encryption;

            if (encryptionSettings.EncryptionCertificateInformation == null)
            {
                throw new ConfigurationErrorsException(
                          $"No encryption certificate information found in SendingPMode {pmode.Id} to perform encryption");
            }

            if (encryptionSettings.EncryptionCertificateInformation is CertificateFindCriteria certFindCriteria)
            {
                return(_certificateRepository.GetCertificate(
                           certFindCriteria.CertificateFindType,
                           certFindCriteria.CertificateFindValue));
            }

            if (encryptionSettings.EncryptionCertificateInformation is PublicKeyCertificate pubKeyCert)
            {
                return(new X509Certificate2(Convert.FromBase64String(pubKeyCert.Certificate), string.Empty));
            }

            throw new NotSupportedException(
                      $"The encryption certificate information specified in the Sending PMode {pmode.Id} could not be used to retrieve the certificate");
        }
        private async Task DeleteEpaDetails(DeleteBatchEpaRequest request)
        {
            _logger.LogInformation("DeleteEpaDetails Before Get Certificate from db");
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (certificate is null)
            {
                throw new NotFound();
            }
            else
            {
                _logger.LogInformation("DeleteEpaDetails Before Removing EpaDetails CertificateData");
                var certData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);
                certData.EpaDetails = new EpaDetails {
                    Epas = new List <EpaRecord>()
                };
                certificate.CertificateData = JsonConvert.SerializeObject(certData);
                await _certificateRepository.Update(certificate, ExternalApiConstants.ApiUserName, CertificateActions.Epa);
            }

            _logger.LogInformation("DeleteEpaDetails Before set Certificate to Deleted in db");
            await _certificateRepository.Delete(request.Uln, request.StandardCode, ExternalApiConstants.ApiUserName, CertificateActions.Delete);

            _logger.LogInformation("DeleteEpaDetails Certificate set to Deleted in db");
        }
        public async Task <Certificate> Handle(StartCertificateRequest request, CancellationToken cancellationToken)
        {
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (certificate == null)
            {
                certificate = await CreateNewCertificate(request);
            }
            else if (certificate.Status == Domain.Consts.CertificateStatus.Deleted)
            {
                _logger.LogInformation("CreateNewCertificate Before Get Ilr from db");
                var ilr = await _ilrRepository.Get(request.Uln, request.StandardCode);

                if (ilr != null)
                {
                    var certData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);
                    certData.LearnerGivenNames    = ilr.GivenNames;
                    certData.LearnerFamilyName    = ilr.FamilyName;
                    certData.LearningStartDate    = ilr.LearnStartDate;
                    certData.FullName             = $"{ilr.GivenNames} {ilr.FamilyName}";
                    certificate.CertificateData   = JsonConvert.SerializeObject(certData);
                    certificate.IsPrivatelyFunded = false;
                    await _certificateRepository.Update(certificate, request.Username, null);
                }
            }
            return(certificate);
        }
        public async Task <Unit> Handle(CertificateReprintRequest request, CancellationToken cancellationToken)
        {
            var certificate = await _certificateRepository.GetCertificate(request.CertificateReference, request.LastName, request.AchievementDate);

            if (certificate == null)
            {
                throw new NotFound();
            }

            if (certificate.Status == CertificateStatus.Reprint)
            {
                return(Unit.Value);
            }

            if (CertificateStatus.CanRequestDuplicateCertificate(certificate.Status))
            {
                certificate.Status = CertificateStatus.Reprint;
                await _certificateRepository.Update(certificate, request.Username, CertificateActions.Reprint);
            }
            else
            {
                throw new NotFound();
            }

            return(Unit.Value);
        }
Example #11
0
        private async Task <Certificate> CreateNewCertificate(CreateBatchCertificateRequest request)
        {
            _logger.LogInformation("CreateNewCertificate Before Get Ilr from db");
            var ilr = await _ilrRepository.Get(request.Uln, request.StandardCode);

            if (ilr is null)
            {
                _logger.LogWarning($"CreateNewCertificate Did not find ILR for Uln {request.Uln} and StandardCode {request.StandardCode}");
                return(null);
            }

            _logger.LogInformation("CreateNewCertificate Before Get Organisation from db");
            var organisation = await _organisationQueryRepository.GetByUkPrn(request.UkPrn);

            _logger.LogInformation("CreateNewCertificate Before Get Standard from API");
            var standard = await _standardService.GetStandard(ilr.StdCode);

            _logger.LogInformation("CreateNewCertificate Before Get Provider from API");
            var provider = await GetProviderFromUkprn(ilr.UkPrn);

            var certData = CombineCertificateData(request.CertificateData, ilr, standard, provider);

            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (certificate == null)
            {
                _logger.LogInformation("CreateNewCertificate Before create new Certificate");
                certificate = await _certificateRepository.New(
                    new Certificate()
                {
                    Uln                  = request.Uln,
                    StandardCode         = request.StandardCode,
                    ProviderUkPrn        = ilr.UkPrn,
                    OrganisationId       = organisation.Id,
                    CreatedBy            = ExternalApiConstants.ApiUserName,
                    CertificateData      = JsonConvert.SerializeObject(certData),
                    Status               = CertificateStatus.Draft, // NOTE: Web & Staff always creates Draft first
                    CertificateReference = string.Empty,
                    LearnRefNumber       = ilr.LearnRefNumber,
                    CreateDay            = DateTime.UtcNow.Date
                });
            }
            else
            {
                _logger.LogInformation("CreateNewCertificate Before resurrecting deleted Certificate");
                certData.EpaDetails.EpaReference = certificate.CertificateReference;
                certificate.CertificateData      = JsonConvert.SerializeObject(certData);
                certificate.Status = CertificateStatus.Draft;
                await _certificateRepository.Update(certificate, ExternalApiConstants.ApiUserName, CertificateActions.Start);
            }

            _logger.LogInformation(LoggingConstants.CertificateStarted);
            _logger.LogInformation($"Certificate with ID: {certificate.Id} Started with reference of {certificate.CertificateReference}");

            return(await CertificateHelpers.ApplyStatusInformation(_certificateRepository, _contactQueryRepository, certificate));
        }
        public GetBatchCertificateRequestValidator(IStringLocalizer <GetBatchCertificateRequestValidator> localiser, IOrganisationQueryRepository organisationQueryRepository, ILearnerRepository learnerRepository, ICertificateRepository certificateRepository, IStandardService standardService)
        {
            RuleFor(m => m.UkPrn).InclusiveBetween(10000000, 99999999).WithMessage("The UKPRN should contain exactly 8 numbers");

            RuleFor(m => m.FamilyName).NotEmpty().WithMessage("Provide apprentice family name");
            RuleFor(m => m.StandardCode).GreaterThan(0).WithMessage("Provide a valid Standard");

            RuleFor(m => m.Uln).InclusiveBetween(1000000000, 9999999999).WithMessage("ULN should contain exactly 10 numbers").DependentRules(() =>
            {
                When(m => m.StandardCode > 0 && !string.IsNullOrEmpty(m.FamilyName), () =>
                {
                    RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                    {
                        // NOTE: Currently we're making the Certificate & Learner/ILR record both mandatory - this is wrong fixing it!
                        var submittingEpao = await organisationQueryRepository.GetByUkPrn(m.UkPrn);

                        if (submittingEpao is null)
                        {
                            context.AddFailure(new ValidationFailure("UkPrn", "Specified UKPRN not found"));
                        }
                        else
                        {
                            var existingCertificateCreatedByCallingEpao = await certificateRepository.GetCertificateByUlnOrgIdLastnameAndStandardCode(m.Uln, submittingEpao.EndPointAssessorOrganisationId, m.FamilyName, m.StandardCode);

                            if (existingCertificateCreatedByCallingEpao == null)
                            {
                                var requestedLearner    = await learnerRepository.Get(m.Uln, m.StandardCode);
                                var existingCertificate = await certificateRepository.GetCertificate(m.Uln, m.StandardCode);
                                var providedStandards   = await standardService.GetEpaoRegisteredStandards(submittingEpao.EndPointAssessorOrganisationId);

                                if (!providedStandards.Any(s => s.StandardCode == m.StandardCode))
                                {
                                    context.AddFailure(new ValidationFailure("StandardCode", "Your organisation is not approved to assess this Standard"));
                                }

                                if (existingCertificate != null)
                                {
                                    var certData = JsonConvert.DeserializeObject <CertificateData>(existingCertificate.CertificateData ?? "{}");

                                    if (!certData.LearnerFamilyName.Equals(m.FamilyName, StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        context.AddFailure(new ValidationFailure("FamilyName", $"Cannot find apprentice with the specified Uln, FamilyName & Standard"));
                                    }
                                    else if (!EpaOutcome.Pass.Equals(certData.EpaDetails?.LatestEpaOutcome, StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        context.AddFailure(new ValidationFailure("Uln", $"Cannot find certificate with the specified Uln, FamilyName & Standard"));
                                    }
                                }
                                else if (requestedLearner is null || !string.Equals(requestedLearner.FamilyName, m.FamilyName, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    context.AddFailure(new ValidationFailure("Uln", "Cannot find apprentice with the specified Uln, FamilyName & Standard"));
                                }
                            }
                        }
                    });
Example #13
0
        /// <summary>
        /// Client side request for authorization token
        /// </summary>
        /// <param name="context">context</param>
        /// <param name="subject">subject of the request (null to default use client configuration)</param>
        /// <returns>JWT token</returns>
        public async Task <string> CreateRequestToken(IWorkContext context, string subject = null)
        {
            Verify.IsNotNull(nameof(context), context);
            context = context.WithTag(_tag);

            X509Certificate2 certificate = await _certificateRepository.GetCertificate(context, _clientTokenManagerConfiguration.RequestSigningCertificateKey, true);

            subject = subject ?? _clientTokenManagerConfiguration.TokenKey.RequestingSubject;
            Verify.IsNotEmpty(nameof(subject), subject);

            string token = new JwtTokenBuilder()
                           .AddSubject(subject)
                           .SetIssuer(_clientTokenManagerConfiguration.RequestingIssuer)
                           .SetExpires(DateTime.Now.AddMinutes(5))
                           .SetIssuedAt(DateTime.Now)
                           .SetCertificate(certificate)
                           .Build();

            return(token);
        }
Example #14
0
        public async Task <Certificate> Handle(StaffCertificateDuplicateRequest request,
                                               CancellationToken cancellationToken)
        {
            var certificate = await _certificateRepository.GetCertificate(request.Id);

            if (CertificateStatus.CanRequestDuplicateCertificate(certificate.Status))
            {
                certificate.Status = CertificateStatus.Reprint;
                await _certificateRepository.Update(certificate, request.Username, action : CertificateActions.Reprint);
            }

            return(certificate);
        }
Example #15
0
        private async Task <EpaDetails> CreateNewEpa(CreateBatchEpaRequest request)
        {
            _logger.LogInformation("CreateNewEpa Before Get Certificate from db");
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (certificate is null)
            {
                _logger.LogInformation("CreateNewEpa Before StartCertificateRequest");
                var startCertificateRequest = new StartCertificateRequest {
                    StandardCode = request.StandardCode, UkPrn = request.UkPrn, Uln = request.Uln, Username = ExternalApiConstants.ApiUserName
                };
                certificate = await _mediator.Send(startCertificateRequest);
            }
            else
            {
                certificate = EpaHelpers.ResetCertificateData(certificate);
            }

            if (certificate is null)
            {
                _logger.LogError($"CreateNewEpa StartCertificateRequest did not create Certificate for Uln {request.Uln} StandardCode {request.StandardCode}");
                throw new NotFound();
            }
            certificate.Status = Domain.Consts.CertificateStatus.Draft;

            _logger.LogInformation("CreateNewEpa Before Resetting Certificate Data");
            var certData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);

            _logger.LogInformation("CreateNewEpa Before Adding EPAs");
            if (request.EpaDetails?.Epas != null)
            {
                foreach (var epa in request.EpaDetails.Epas)
                {
                    epa.EpaOutcome = EpaHelpers.NormalizeEpaOutcome(epa.EpaOutcome);
                    certData.EpaDetails.Epas.Add(epa);
                }
            }

            var latestEpaRecord = certData.EpaDetails.Epas.OrderByDescending(epa => epa.EpaDate).FirstOrDefault();

            certData.EpaDetails.LatestEpaDate    = latestEpaRecord?.EpaDate;
            certData.EpaDetails.LatestEpaOutcome = latestEpaRecord?.EpaOutcome;

            _logger.LogInformation("CreateNewEpa Before Update CertificateData");
            certificate.CertificateData = JsonConvert.SerializeObject(certData);

            _logger.LogInformation("CreateNewEpa Before Update Cert in db");
            await _certificateRepository.Update(certificate, ExternalApiConstants.ApiUserName, CertificateActions.Epa);

            return(certData.EpaDetails);
        }
        public async Task <LearnerDetail> Handle(LearnerDetailRequest request, CancellationToken cancellationToken)
        {
            var learner = await _ilrRepository.Get(request.Uln, request.StdCode);

            var standard = await _standardRepository.GetStandardCollationByStandardId(request.StdCode);

            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StdCode);

            var logs            = new List <CertificateLogSummary>();
            var certificateData = new CertificateData();
            var epao            = new Organisation();

            if (certificate != null)
            {
                logs = await _staffCertificateRepository.GetCertificateLogsFor(certificate.Id, request.AllRecords);

                if (logs.Count() > 1)
                {
                    CalculateDifferences(logs);
                }

                certificateData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData) ?? new CertificateData();
                epao            = await _organisationRepository.Get(certificate.OrganisationId) ?? new Organisation();
            }

            var learnerDetail = new LearnerDetail()
            {
                Uln                         = request.Uln,
                FamilyName                  = !string.IsNullOrEmpty(certificateData.LearnerFamilyName) ? certificateData.LearnerFamilyName : learner?.FamilyName,
                GivenNames                  = !string.IsNullOrEmpty(certificateData.LearnerGivenNames) ? certificateData.LearnerGivenNames : learner?.GivenNames,
                LearnStartDate              = certificateData.LearningStartDate.HasValue ? certificateData.LearningStartDate : learner?.LearnStartDate,
                StandardCode                = (certificate?.StandardCode).HasValue ? certificate.StandardCode : standard?.StandardId ?? 0,
                Standard                    = !string.IsNullOrEmpty(certificateData.StandardName) ? certificateData.StandardName : standard?.Title,
                Level                       = certificateData.StandardLevel > 0 ? certificateData.StandardLevel : standard?.StandardData?.Level ?? 0,
                CertificateReference        = certificate?.CertificateReference,
                CertificateStatus           = certificate?.Status,
                OverallGrade                = certificateData.OverallGrade,
                AchievementDate             = certificateData.AchievementDate, //?.UtcToTimeZoneTime(),
                Option                      = certificateData.CourseOption,
                OrganisationName            = epao.EndPointAssessorName,
                OrganisationId              = epao.EndPointAssessorOrganisationId,
                CertificateLogs             = logs,
                FundingModel                = learner?.FundingModel,
                CompletionStatus            = learner?.CompletionStatus,
                CompletionStatusDescription = FormatCompletionStatusDescription(learner?.CompletionStatus),
                IsPrivatelyFunded           = certificate?.IsPrivatelyFunded,
                CertificateId               = certificate?.Id
            };

            return(learnerDetail);
        }
        private async Task <Certificate> GetCertificate(GetBatchCertificateRequest request)
        {
            _logger.LogInformation("GetCertificate Before Get Certificate from db");
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            _logger.LogInformation("GetCertificate Before Get Searching Organisation from db");
            var searchingOrganisation = await _organisationQueryRepository.GetByUkPrn(request.UkPrn);

            var allowedCertificateStatus = new string[] { CertificateStatus.Draft, CertificateStatus.Submitted, CertificateStatus.Printed, CertificateStatus.Reprint };

            if (certificate != null && searchingOrganisation != null && allowedCertificateStatus.Contains(certificate.Status))
            {
                var certData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);

                if (string.Equals(certData.LearnerFamilyName, request.FamilyName, StringComparison.InvariantCultureIgnoreCase))
                {
                    certificate = await CertificateHelpers.ApplyStatusInformation(_certificateRepository, _contactQueryRepository, certificate);

                    if (!EpaOutcome.Pass.Equals(certData.EpaDetails?.LatestEpaOutcome, StringComparison.InvariantCultureIgnoreCase))
                    {
                        // As EPA has not passed, only give access to basic information & EPA Details
                        certificate = RedactCertificateInformation(certificate, true);
                    }

                    if (certificate.OrganisationId != searchingOrganisation.Id)
                    {
                        var providedStandards = await _standardRepository.GetEpaoRegisteredStandards(searchingOrganisation.EndPointAssessorOrganisationId, short.MaxValue, null);

                        if (providedStandards.PageOfResults.Any(s => s.StandardCode == certificate.StandardCode))
                        {
                            // Shared standard but not the EPAO who created the certificate
                            certificate = RedactCertificateInformation(certificate, false);
                        }
                        else
                        {
                            certificate = null;
                        }
                    }
                }
                else
                {
                    certificate = null;
                }
            }
            else
            {
                certificate = null;
            }

            return(certificate);
        }
Example #18
0
        private async Task <string> HandleSameSourceRequest(Ilr learner, ImportLearnerDetail importLearnerDetail, CancellationToken cancellationToken)
        {
            if (importLearnerDetail.Ukprn == learner.UkPrn)
            {
                if (importLearnerDetail.LearnActEndDate != null && importLearnerDetail.LearnStartDate == importLearnerDetail.LearnActEndDate)
                {
                    return("IgnoreLearnActEndDateSameAsLearnStartDate");
                }

                if (importLearnerDetail.PlannedEndDate == learner.PlannedEndDate && importLearnerDetail.LearnStartDate == learner.LearnStartDate)
                {
                    return(await UpdateIlrRecord(importLearnerDetail, true, learner));
                }

                if (importLearnerDetail.LearnStartDate > learner.LearnStartDate)
                {
                    return(await UpdateIlrRecord(importLearnerDetail, false));
                }
            }
            else
            {
                var certificate = await _certificateRepository.GetCertificate(importLearnerDetail.Uln.Value, importLearnerDetail.StdCode.Value);

                if (certificate != null)
                {
                    return("IgnoreUkprnChangedButCertficateAlreadyExists");
                }

                if (importLearnerDetail.FundingModel == 99 && learner.FundingModel != 99)
                {
                    return("IgnoreFundingModelChangedTo99WhenPrevioulsyNot99");
                }

                if (importLearnerDetail.LearnActEndDate == null && learner.LearnActEndDate != null)
                {
                    return(await UpdateIlrRecord(importLearnerDetail, false));
                }

                if (importLearnerDetail.LearnActEndDate != null && importLearnerDetail.PlannedEndDate > learner.PlannedEndDate)
                {
                    return(await UpdateIlrRecord(importLearnerDetail, false));
                }

                if (importLearnerDetail.LearnStartDate > learner.LearnStartDate)
                {
                    return(await UpdateIlrRecord(importLearnerDetail, false));
                }
            }

            return("IgnoreOutOfDate");
        }
        protected override X509Certificate2 LoadCertificate()
        {
            if (String.IsNullOrWhiteSpace(_certificateSerialNr))
            {
                throw new InvalidOperationException("Unable to retrieve Certificate: No X509SerialNumber available.");
            }

            if (_certificateRepository == null)
            {
                throw new InvalidOperationException("Unable to retrieve Certificate: No CertificateRepository defined.");
            }

            return(_certificateRepository.GetCertificate(X509FindType.FindBySerialNumber, _certificateSerialNr));
        }
        public UpdateBatchEpaRequestValidator(IStringLocalizer <BatchEpaRequestValidator> localiser, IOrganisationQueryRepository organisationQueryRepository, IIlrRepository ilrRepository, ICertificateRepository certificateRepository, IStandardService standardService)
        {
            Include(new BatchEpaRequestValidator(localiser, organisationQueryRepository, ilrRepository, standardService));

            RuleFor(m => m.EpaDetails.EpaReference).NotEmpty().WithMessage("Provide EPA reference").DependentRules(() =>
            {
                RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                {
                    var existingCertificate = await certificateRepository.GetCertificate(m.Uln, m.StandardCode);
                    var sumbittingEpao      = await organisationQueryRepository.GetByUkPrn(m.UkPrn);

                    if (existingCertificate is null || !string.Equals(existingCertificate.CertificateReference, m.EpaDetails.EpaReference, StringComparison.InvariantCultureIgnoreCase))
                    {
                        context.AddFailure(new ValidationFailure("EpaReference", $"EPA not found"));
                    }
Example #21
0
        private async Task <Certificate> GetCertificate(GetBatchCertificateRequest request)
        {
            _logger.LogInformation("GetCertificate Before Get Certificate from db");
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode, request.FamilyName, request.IncludeLogs);

            _logger.LogInformation("GetCertificate Before Get Searching Organisation from db");
            var searchingOrganisation = await _organisationQueryRepository.GetByUkPrn(request.UkPrn);

            var allowedCertificateStatus = new[] { CertificateStatus.Draft, CertificateStatus.Submitted }.Concat(CertificateStatus.PrintProcessStatus);

            if (certificate == null || searchingOrganisation == null || !allowedCertificateStatus.Contains(certificate.Status))
            {
                return(null);
            }

            var certData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);

            certificate = await CertificateHelpers.ApplyStatusInformation(_certificateRepository, _contactQueryRepository, certificate);

            if ((certificate.Status == CertificateStatus.Submitted || CertificateStatus.HasPrintProcessStatus(certificate.Status)) && certData.OverallGrade == CertificateGrade.Fail)
            {
                return(null);
            }
            else if (certificate.Status == CertificateStatus.Draft &&
                     EpaOutcome.Pass.Equals(certData.EpaDetails?.LatestEpaOutcome, StringComparison.InvariantCultureIgnoreCase) &&
                     certData.OverallGrade == null)
            {
                return(null);
            }

            if (certificate.OrganisationId != searchingOrganisation.Id)
            {
                var providedStandards = await _standardRepository.GetEpaoRegisteredStandards(searchingOrganisation.EndPointAssessorOrganisationId, int.MaxValue, 1);

                if (providedStandards.PageOfResults.Any(s => s.StandardCode == certificate.StandardCode))
                {
                    // Shared standard but not the EPAO who created the certificate
                    certificate = RedactCertificateInformation(certificate, false);
                }
                else
                {
                    certificate = null;
                }
            }

            return(certificate);
        }
        public async Task <Certificate> Handle(UpdateCertificateRequestReprintCommand request, CancellationToken cancellationToken)
        {
            var certificate = await _certificateRepository.GetCertificate(request.CertificateId);

            if (certificate == null)
            {
                throw new NotFoundException();
            }

            if (certificate.Status != CertificateStatus.Reprint && CertificateStatus.CanRequestReprintCertificate(certificate.Status))
            {
                certificate.Status = CertificateStatus.Reprint;
                await _certificateRepository.Update(certificate, request.Username, CertificateActions.Reprint);
            }

            return(certificate);
        }
Example #23
0
        public UpdateBatchCertificateRequestValidator(IStringLocalizer <BatchCertificateRequestValidator> localiser, IOrganisationQueryRepository organisationQueryRepository, IIlrRepository ilrRepository, ICertificateRepository certificateRepository, IStandardService standardService)
        {
            Include(new BatchCertificateRequestValidator(localiser, organisationQueryRepository, ilrRepository, certificateRepository, standardService));

            RuleFor(m => m.CertificateReference).NotEmpty().WithMessage("Provide the certificate reference").DependentRules(() =>
            {
                // TODO: ON-2130 Consider in the future how to merge both create & update versions as the Cert will always exist due to EPA
                RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                {
                    var existingCertificate = await certificateRepository.GetCertificate(m.Uln, m.StandardCode);
                    var sumbittingEpao      = await organisationQueryRepository.GetByUkPrn(m.UkPrn);

                    if (existingCertificate is null || !string.Equals(existingCertificate.CertificateReference, m.CertificateReference, StringComparison.InvariantCultureIgnoreCase) ||
                        existingCertificate.Status == CertificateStatus.Deleted)
                    {
                        context.AddFailure(new ValidationFailure("CertificateReference", $"Certificate not found"));
                    }
Example #24
0
        public async Task <Certificate> Handle(StartCertificateRequest request, CancellationToken cancellationToken)
        {
            _logger.LogDebug($"Starting new certificate for EPAO UkPrn:{request.UkPrn}");
            var organisation = await _organisationQueryRepository.GetByUkPrn(request.UkPrn);

            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (certificate == null)
            {
                certificate = await CreateNewCertificate(request, organisation);
            }
            else
            {
                certificate = await UpdateExistingCertificate(request, organisation, certificate);
            }

            return(certificate);
        }
Example #25
0
        private async Task <EpaDetails> UpdateEpaDetails(UpdateBatchEpaRequest request)
        {
            _logger.LogInformation("UpdateEpaDetails Before Get Certificate from db");
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (certificate is null)
            {
                throw new NotFound();
            }
            else
            {
                certificate = EpaHelpers.ResetCertificateData(certificate);
            }

            _logger.LogInformation("UpdateEpaDetails Before Combining EpaDetails");
            var certData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);

            certData.EpaDetails = new EpaDetails {
                EpaReference = certificate.CertificateReference, Epas = new List <EpaRecord>()
            };

            if (request.EpaDetails?.Epas != null)
            {
                foreach (var epa in request.EpaDetails.Epas)
                {
                    epa.EpaOutcome = EpaHelpers.NormalizeEpaOutcome(epa.EpaOutcome);
                    certData.EpaDetails.Epas.Add(epa);
                }
            }

            var latestEpaRecord = certData.EpaDetails.Epas.OrderByDescending(epa => epa.EpaDate).FirstOrDefault();

            certData.EpaDetails.LatestEpaDate    = latestEpaRecord?.EpaDate;
            certData.EpaDetails.LatestEpaOutcome = latestEpaRecord?.EpaOutcome;

            _logger.LogInformation("UpdateEpaDetails Before Update CertificateData");
            certificate.CertificateData = JsonConvert.SerializeObject(certData);

            _logger.LogInformation("UpdateEpaDetails Before Update Cert in db");
            await _certificateRepository.Update(certificate, ExternalApiConstants.ApiUserName, CertificateActions.Epa);

            return(certData.EpaDetails);
        }
        private async Task <Certificate> SubmitCertificate(SubmitBatchCertificateRequest request)
        {
            _logger.LogInformation("SubmitCertificate Before Get Certificate from db");
            var certificate = await _certificateRepository.GetCertificate(request.Uln, request.StandardCode);

            if (certificate != null)
            {
                _logger.LogInformation("SubmitCertificate Before Update Certificate Status");
                certificate.Status = CertificateStatus.Submitted;

                _logger.LogInformation("SubmitCertificate Before Update Cert in db");
                var submittedCertificate = await _certificateRepository.Update(certificate, ExternalApiConstants.ApiUserName, CertificateActions.Submit);

                return(await CertificateHelpers.ApplyStatusInformation(_certificateRepository, _contactQueryRepository, submittedCertificate));
            }
            else
            {
                _logger.LogWarning($"SubmitCertificate Did not find Certificate for Uln {request.Uln} and StandardCode {request.StandardCode}");
                return(null);
            }
        }
        public CreateBatchEpaRequestValidator(IStringLocalizer <BatchEpaRequestValidator> localiser, IOrganisationQueryRepository organisationQueryRepository, IIlrRepository ilrRepository, ICertificateRepository certificateRepository, IStandardService standardService)
        {
            Include(new BatchEpaRequestValidator(localiser, organisationQueryRepository, ilrRepository, standardService));

            RuleFor(m => m.EpaDetails.EpaReference).Empty().WithMessage("EPA reference must be empty").DependentRules(() =>
            {
                RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                {
                    var existingCertificate = await certificateRepository.GetCertificate(m.Uln, m.StandardCode);

                    if (existingCertificate != null)
                    {
                        switch (existingCertificate.Status)
                        {
                        case CertificateStatus.Deleted:
                            break;

                        case CertificateStatus.Draft:
                            var certData = JsonConvert.DeserializeObject <CertificateData>(existingCertificate.CertificateData);

                            if (!string.IsNullOrEmpty(certData.OverallGrade) && certData.AchievementDate.HasValue && !string.IsNullOrEmpty(certData.ContactPostCode))
                            {
                                context.AddFailure(new ValidationFailure("EpaDetails", $"Certificate already exists, cannot create EPA record"));
                            }
                            else if (!string.IsNullOrEmpty(certData.EpaDetails?.LatestEpaOutcome))
                            {
                                context.AddFailure(new ValidationFailure("EpaDetails", $"EPA already provided for the learner"));
                            }
                            break;

                        default:
                            context.AddFailure(new ValidationFailure("EpaDetails", $"Certificate already exists, cannot create EPA record"));
                            break;
                        }
                    }
                });
            });
        }
        public CreateBatchEpaRequestValidator(IStringLocalizer <BatchEpaRequestValidator> localiser, IOrganisationQueryRepository organisationQueryRepository, ILearnerRepository learnerRepository, ICertificateRepository certificateRepository, IStandardService standardService)
        {
            Include(new BatchEpaRequestValidator(localiser, organisationQueryRepository, learnerRepository, standardService));

            RuleFor(m => m.EpaDetails.EpaReference).Empty().WithMessage("EPA reference must be empty").DependentRules(() =>
            {
                RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                {
                    var existingCertificate = await certificateRepository.GetCertificate(m.Uln, m.StandardCode);

                    if (existingCertificate != null)
                    {
                        var certData = JsonConvert.DeserializeObject <CertificateData>(existingCertificate.CertificateData);

                        var submittedCertificate      = !(existingCertificate.Status == CertificateStatus.Draft || existingCertificate.Status == CertificateStatus.Deleted);
                        var outcomeIsAFail            = certData.OverallGrade == CertificateGrade.Fail;
                        var outcomeIsAPass            = !outcomeIsAFail;
                        var isDraftCertificate        = existingCertificate.Status == CertificateStatus.Draft;
                        var canUpdateDraftCertificate = string.IsNullOrEmpty(certData.EpaDetails?.LatestEpaOutcome);

                        if (submittedCertificate && outcomeIsAPass)
                        {
                            context.AddFailure(new ValidationFailure("EpaDetails", $"Certificate already exists, cannot create EPA record"));
                        }
                        else if (submittedCertificate && outcomeIsAFail)
                        {
                            context.AddFailure(new ValidationFailure("EpaDetails", $"EPA already provided for the learner"));
                        }
                        else if (isDraftCertificate && !canUpdateDraftCertificate)
                        {
                            context.AddFailure(new ValidationFailure("EpaDetails", $"EPA already provided for the learner"));
                        }
                    }
                });
            });
        }
Example #29
0
        public async Task <GetBatchLearnerResponse> Handle(GetBatchLearnerRequest request, CancellationToken cancellationToken)
        {
            // Get certificate will be called twice.
            // The Get Certificate Handler contains will not return a certificate in certain scenarios
            // but there is information stored in the certificate that we need for learner details

            var standard = await _standardService.GetStandardVersionById(request.Standard);

            if (standard != null)
            {
                var certificateFromRepository = await _certificateRepository.GetCertificate(request.Uln, standard.LarsCode, request.FamilyName);

                var learner = await GetLearnerDetails(request, standard, certificateFromRepository);

                var epaDetails             = GetEpaDetailsFromCertificate(certificateFromRepository);
                var certificateFromHandler = await GetCertificate(request, standard);

                return(new GetBatchLearnerResponse {
                    Learner = learner, Certificate = certificateFromHandler, EpaDetails = epaDetails
                });
            }

            return(new GetBatchLearnerResponse());
        }
        public GetBatchCertificateRequestValidator(IStringLocalizer <GetBatchCertificateRequestValidator> localiser, IOrganisationQueryRepository organisationQueryRepository, IIlrRepository ilrRepository, ICertificateRepository certificateRepository, IStandardService standardService)
        {
            RuleFor(m => m.UkPrn).InclusiveBetween(10000000, 99999999).WithMessage("The UKPRN should contain exactly 8 numbers");

            RuleFor(m => m.FamilyName).NotEmpty().WithMessage("Provide apprentice family name");
            RuleFor(m => m.StandardCode).GreaterThan(0).WithMessage("Provide a valid Standard").DependentRules(() =>
            {
                RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                {
                    if (!string.IsNullOrEmpty(m.StandardReference))
                    {
                        var collatedStandard = await standardService.GetStandard(m.StandardReference);
                        if (m.StandardCode != collatedStandard?.StandardId)
                        {
                            context.AddFailure("StandardReference and StandardCode must be for the same Standard");
                        }
                    }
                });
            });

            RuleFor(m => m.Uln).InclusiveBetween(1000000000, 9999999999).WithMessage("ULN should contain exactly 10 numbers").DependentRules(() =>
            {
                When(m => m.StandardCode > 0 && !string.IsNullOrEmpty(m.FamilyName), () =>
                {
                    RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                    {
                        // NOTE: Currently we're making the Certificate & ILR record both mandatory
                        var requestedIlr   = await ilrRepository.Get(m.Uln, m.StandardCode);
                        var sumbittingEpao = await organisationQueryRepository.GetByUkPrn(m.UkPrn);

                        if (requestedIlr is null || !string.Equals(requestedIlr.FamilyName, m.FamilyName, StringComparison.InvariantCultureIgnoreCase))
                        {
                            context.AddFailure(new ValidationFailure("Uln", "ULN, FamilyName and Standard not found"));
                        }
                        else if (sumbittingEpao is null)
                        {
                            context.AddFailure(new ValidationFailure("UkPrn", "Specified UKPRN not found"));
                        }
                        else
                        {
                            var providedStandards = await standardService.GetEpaoRegisteredStandards(sumbittingEpao.EndPointAssessorOrganisationId);

                            if (!providedStandards.Any(s => s.StandardCode == m.StandardCode))
                            {
                                context.AddFailure(new ValidationFailure("StandardCode", "Your organisation is not approved to assess this Standard"));
                            }
                        }
                    });

                    RuleFor(m => m).CustomAsync(async(m, context, cancellation) =>
                    {
                        var existingCertificate = await certificateRepository.GetCertificate(m.Uln, m.StandardCode);

                        if (existingCertificate is null)
                        {
                            // TODO: FUTURE WORK - ON-2130 Do Alan's Certificate Search THEN the ILR Search (which may be the validation down below)
                        }
                        else
                        {
                            var certData = JsonConvert.DeserializeObject <CertificateData>(existingCertificate.CertificateData ?? "{}");

                            if (!certData.LearnerFamilyName.Equals(m.FamilyName, StringComparison.InvariantCultureIgnoreCase))
                            {
                                context.AddFailure(new ValidationFailure("FamilyName", $"Invalid family name"));
                            }
                            else if (!EpaOutcome.Pass.Equals(certData.EpaDetails?.LatestEpaOutcome, StringComparison.InvariantCultureIgnoreCase))
                            {
                                context.AddFailure(new ValidationFailure("Uln", $"Latest EPA Outcome has not passed"));
                            }
                        }
                    });
                });