public async Task <Certificate> Handle(UpdateCertificateRequest request, CancellationToken cancellationToken)
        {
            if (request.Certificate.Status == Domain.Consts.CertificateStatus.Submitted ||
                request.Certificate.Status == Domain.Consts.CertificateStatus.ToBeApproved)
            {
                _logger.LogInformation(LoggingConstants.CertificateSubmitted);
                _logger.LogInformation($"Certificate with ID: {request.Certificate.Id} Submitted with reference of {request.Certificate.CertificateReference}");

                var certData = JsonConvert.DeserializeObject <CertificateData>(request.Certificate.CertificateData);
                if (certData != null)
                {
                    var epaDetails = certData.EpaDetails ??
                                     new EpaDetails
                    {
                        Epas = new List <EpaRecord>()
                    };

                    var epaOutcome = certData.OverallGrade == CertificateGrade.Fail ? EpaOutcome.Fail : EpaOutcome.Pass;

                    if (certData.AchievementDate != null &&
                        !epaDetails.Epas.Any(rec => rec.EpaDate == certData.AchievementDate.Value && rec.EpaOutcome.Equals(epaOutcome, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        epaDetails.Epas.Add(new EpaRecord
                        {
                            EpaDate    = certData.AchievementDate.Value,
                            EpaOutcome = epaOutcome
                        });

                        // sort pass outcomes before fail outcomes as pass is the final state even if earlier than the fail
                        var latestRecord = epaDetails.Epas
                                           .OrderByDescending(epa => epa.EpaOutcome != EpaOutcome.Fail ? 1 : 0)
                                           .ThenByDescending(epa => epa.EpaDate)
                                           .First();

                        epaDetails.LatestEpaDate    = latestRecord.EpaDate;
                        epaDetails.LatestEpaOutcome = latestRecord.EpaOutcome;
                        epaDetails.EpaReference     = request.Certificate.CertificateReference;
                    }

                    certData.EpaDetails = epaDetails;
                    request.Certificate.CertificateData = JsonConvert.SerializeObject(certData);
                }
            }

            // NOTE: Unlike UpdateBatchCertificateHandler (External API) the status is altered from the UI in all cases

            var logs = await _certificateRepository.GetCertificateLogsFor(request.Certificate.Id);

            var latestLogEntry = logs.OrderByDescending(l => l.EventTime).FirstOrDefault();

            if (latestLogEntry != null && latestLogEntry.Action == request.Action && string.IsNullOrWhiteSpace(request.ReasonForChange))
            {
                return(await _certificateRepository.Update(request.Certificate, request.Username, request.Action, updateLog : false));
            }

            return(await _certificateRepository.Update(request.Certificate, request.Username, request.Action, updateLog : true, reasonForChange : request.ReasonForChange));
        }
        private async Task <Certificate> Update(UpdateCertificateRequest request)
        {
            var logs = await _certificateRepository.GetCertificateLogsFor(request.Certificate.Id);

            var latestLogEntry = logs.OrderByDescending(l => l.EventTime).FirstOrDefault();

            if (latestLogEntry != null && latestLogEntry.Action == request.Action && latestLogEntry.CertificateData == request.Certificate.CertificateData && string.IsNullOrWhiteSpace(request.ReasonForChange))
            {
                return(await _certificateRepository.Update(request.Certificate, request.Username, request.Action, updateLog : false));
            }

            return(await _certificateRepository.Update(request.Certificate, request.Username, request.Action, updateLog : true, reasonForChange : request.ReasonForChange));
        }
Example #3
0
        public static async Task <Certificate> ApplyStatusInformation(ICertificateRepository certificateRepository, IContactQueryRepository contactQueryRepository, Certificate certificate)
        {
            if (certificateRepository is null || contactQueryRepository is null || certificate is null)
            {
                return(certificate);
            }

            var json = JsonConvert.SerializeObject(certificate);
            var cert = JsonConvert.DeserializeObject <Certificate>(json);

            var certificateLogs = await certificateRepository.GetCertificateLogsFor(cert.Id);

            certificateLogs = certificateLogs?.Where(l => l.ReasonForChange is null).ToList(); // this removes any admin changes done within staff app

            var createdLogEntry = certificateLogs?.OrderByDescending(l => l.EventTime).FirstOrDefault(l => l.Status == CertificateStatus.Draft && l.Action == CertificateActions.Start);

            if (createdLogEntry != null)
            {
                var createdContact = await contactQueryRepository.GetContact(createdLogEntry.Username);

                cert.CreatedAt = createdLogEntry.EventTime.UtcToTimeZoneTime();
                cert.CreatedBy = createdContact != null ? createdContact.DisplayName : createdLogEntry.Username;
            }

            var submittedLogEntry = certificateLogs?.OrderByDescending(l => l.EventTime).FirstOrDefault(l => l.Status == CertificateStatus.Submitted);

            // NOTE: THIS IS A DATA FRIG FOR EXTERNAL API AS WE NEED SUBMITTED INFORMATION!
            // Amended, don't return submitted info, if the status has returned to draft after a fail.
            if (submittedLogEntry != null && certificate.Status != CertificateStatus.Draft)
            {
                var submittedContact = await contactQueryRepository.GetContact(submittedLogEntry.Username);

                cert.UpdatedAt = submittedLogEntry.EventTime.UtcToTimeZoneTime();
                cert.UpdatedBy = submittedContact != null ? submittedContact.DisplayName : submittedLogEntry.Username;
            }
            else
            {
                cert.UpdatedAt = null;
                cert.UpdatedBy = null;
            }

            // Remove Print & Batch information if going for a Reprint
            if (cert.Status == CertificateStatus.Reprint)
            {
                cert.ToBePrinted = null;
                cert.BatchNumber = null;
            }

            return(cert);
        }
Example #4
0
        public static List <SearchResult> MatchUpExistingCompletedStandards(this List <SearchResult> searchResults, SearchQuery request, ICertificateRepository certificateRepository, IContactQueryRepository contactRepository, IOrganisationQueryRepository _organisationRepository, ILogger <SearchHandler> logger)
        {
            logger.LogInformation("MatchUpExistingCompletedStandards Before Get Certificates for uln from db");
            var completedCertificates = certificateRepository.GetCompletedCertificatesFor(request.Uln).Result;

            logger.LogInformation("MatchUpExistingCompletedStandards After Get Certificates for uln from db");

            var searchingEpao = _organisationRepository.Get(request.EpaOrgId).Result;

            foreach (var searchResult in searchResults.Where(r => completedCertificates.Select(s => s.StandardCode).Contains(r.StdCode)))
            {
                var certificate     = completedCertificates.Single(s => s.StandardCode == searchResult.StdCode);
                var certificateData = JsonConvert.DeserializeObject <CertificateData>(certificate.CertificateData);
                searchResult.CertificateReference = certificate.CertificateReference;
                searchResult.CertificateId        = certificate.Id;
                searchResult.CertificateStatus    = certificate.Status;
                searchResult.LearnStartDate       = certificateData.LearningStartDate;
                searchResult.Option = certificateData.CourseOption;

                var certificateLogs = certificateRepository.GetCertificateLogsFor(certificate.Id).Result;
                logger.LogInformation("MatchUpExistingCompletedStandards After GetCertificateLogsFor");
                var submittedLogEntry = certificateLogs.FirstOrDefault(l => l.Status == CertificateStatus.Submitted);
                var createdLogEntry   = certificateLogs.FirstOrDefault(l => l.Status == CertificateStatus.Draft);
                if (request.IsPrivatelyFunded)
                {
                    var toBeApprovedLogEntry = certificateLogs.FirstOrDefault(l => l.Status == CertificateStatus.ToBeApproved);
                    if (toBeApprovedLogEntry == null)
                    {
                        continue;
                    }
                    submittedLogEntry = toBeApprovedLogEntry;
                }

                if (submittedLogEntry == null)
                {
                    continue;
                }

                var submittingContact = contactRepository.GetContact(submittedLogEntry.Username).Result ?? contactRepository.GetContact(certificate.UpdatedBy).Result;
                var createdContact    = contactRepository.GetContact(createdLogEntry?.Username).Result ?? contactRepository.GetContact(certificate.CreatedBy).Result;

                var lastUpdatedLogEntry = certificateLogs.Aggregate((i1, i2) => i1.EventTime > i2.EventTime ? i1 : i2) ?? submittedLogEntry;
                var lastUpdatedContact  = contactRepository.GetContact(lastUpdatedLogEntry.Username).Result;

                logger.LogInformation("MatchUpExistingCompletedStandards After GetContact");

                var searchingContact = contactRepository.GetContact(request.Username).Result;

                if (submittingContact != null && submittingContact.OrganisationId == searchingContact.OrganisationId)
                {
                    searchResult.ShowExtraInfo = true;
                    searchResult.OverallGrade  = certificateData.OverallGrade;
                    searchResult.SubmittedBy   = submittingContact.DisplayName;                                                              // This needs to be contact real name
                    searchResult.SubmittedAt   = submittedLogEntry.EventTime.UtcToTimeZoneTime();                                            // This needs to be local time
                    searchResult.AchDate       = certificateData.AchievementDate;
                    searchResult.UpdatedBy     = lastUpdatedContact != null ? lastUpdatedContact.DisplayName : lastUpdatedLogEntry.Username; // This needs to be contact real name
                    searchResult.UpdatedAt     = lastUpdatedLogEntry.EventTime.UtcToTimeZoneTime();                                          // This needs to be local time
                }
                else if (createdContact != null && searchingContact != null && createdContact.OrganisationId == searchingContact.OrganisationId)
                {
                    searchResult.ShowExtraInfo = true;
                    searchResult.OverallGrade  = certificateData.OverallGrade;
                    searchResult.SubmittedBy   = submittedLogEntry.Username;                                                                 // This needs to be contact real name
                    searchResult.SubmittedAt   = submittedLogEntry.EventTime.UtcToTimeZoneTime();                                            // This needs to be local time
                    searchResult.AchDate       = certificateData.AchievementDate;
                    searchResult.UpdatedBy     = lastUpdatedContact != null ? lastUpdatedContact.DisplayName : lastUpdatedLogEntry.Username; // This needs to be contact real name
                    searchResult.UpdatedAt     = lastUpdatedLogEntry.EventTime.UtcToTimeZoneTime();                                          // This needs to be local time
                }
                else if (certificate.OrganisationId == searchingEpao?.Id)
                {
                    searchResult.ShowExtraInfo = true;
                    searchResult.OverallGrade  = certificateData.OverallGrade;
                    searchResult.SubmittedBy   = submittedLogEntry.Username ?? certificate.UpdatedBy;
                    searchResult.SubmittedAt   = submittedLogEntry.EventTime.UtcToTimeZoneTime(); // This needs to be local time
                    searchResult.AchDate       = certificateData.AchievementDate;
                    searchResult.UpdatedBy     = lastUpdatedLogEntry.Username ?? certificate.UpdatedBy;
                    searchResult.UpdatedAt     = lastUpdatedLogEntry.EventTime.UtcToTimeZoneTime(); // This needs to be local time
                }
                else
                {
                    searchResult.ShowExtraInfo  = false;
                    searchResult.OverallGrade   = "";
                    searchResult.SubmittedBy    = "";
                    searchResult.SubmittedAt    = null;
                    searchResult.LearnStartDate = null;
                    searchResult.AchDate        = null;
                    searchResult.UpdatedBy      = null;
                    searchResult.UpdatedAt      = null;
                }
            }

            return(searchResults);
        }