private DateTime GetUpdatedStatusDate(string learnerCertificateStatus)
 {
     if (CertificateStatus.HasPrintNotificateStatus(learnerCertificateStatus))
     {
         if (Learner.PrintStatusAt != null)
         {
             return((DateTime)Learner.PrintStatusAt);
         }
     }
     if (Learner.LastUpdatedAt != null)
     {
         return((DateTime)Learner.LastUpdatedAt);
     }
     return(default);
        private async Task <CertificatePrintStatusUpdate> Validate(CertificatePrintStatusUpdate certificatePrintStatus, ValidationResponse validationResult)
        {
            if (!CertificateStatus.HasPrintNotificateStatus(certificatePrintStatus.Status))
            {
                validationResult.Errors.Add(
                    new ValidationErrorDetail("CertificatePrintStatuses", $"The certificate status {certificatePrintStatus.Status} is not a valid print notification status.", ValidationStatusCode.BadRequest));
            }

            if (!await IsValidBatchNumber(certificatePrintStatus.BatchNumber))
            {
                validationResult.Errors.Add(
                    new ValidationErrorDetail("BatchNumber", $"The batch number {certificatePrintStatus.BatchNumber} was not found.", ValidationStatusCode.NotFound));
            }

            return(validationResult.Errors.Count == 0
                ? certificatePrintStatus
                : null);
        }
        public async Task <ValidationResponse> Handle(CertificatePrintStatusUpdateRequest request, CancellationToken cancellationToken)
        {
            var validationResult = new ValidationResponse();

            var validatedCertificatePrintStatus = await Validate(request, validationResult);

            if (validatedCertificatePrintStatus != null)
            {
                var certificate = await _certificateRepository.GetCertificate(validatedCertificatePrintStatus.CertificateReference);

                if (certificate == null)
                {
                    validationResult.Errors.Add(
                        new ValidationErrorDetail(
                            "CertificateReference",
                            $"The certificate reference {validatedCertificatePrintStatus.CertificateReference} was not found.",
                            ValidationStatusCode.NotFound));

                    return(validationResult);
                }

                var certificateBatchLog = await _batchLogQueryRepository.GetCertificateBatchLog(validatedCertificatePrintStatus.BatchNumber, validatedCertificatePrintStatus.CertificateReference);

                if (certificateBatchLog == null)
                {
                    validationResult.Errors.Add(
                        new ValidationErrorDetail(
                            "CertificateReference",
                            $"Certificate {validatedCertificatePrintStatus.CertificateReference} not printed in batch {validatedCertificatePrintStatus.BatchNumber}.",
                            ValidationStatusCode.NotFound));

                    return(validationResult);
                }

                if (validatedCertificatePrintStatus.StatusAt < certificateBatchLog.StatusAt)
                {
                    validationResult.Errors.Add(
                        new ValidationErrorDetail(
                            "StatusChangedDateTime",
                            $"Certificate {validatedCertificatePrintStatus.CertificateReference} {validatedCertificatePrintStatus.Status} at {validatedCertificatePrintStatus.StatusAt} is earlier than {certificateBatchLog.Status} at {certificateBatchLog.StatusAt}.",
                            ValidationStatusCode.Warning));
                }

                var duplicateUpdate =
                    validatedCertificatePrintStatus.StatusAt == certificateBatchLog.StatusAt &&
                    validatedCertificatePrintStatus.Status == certificateBatchLog.Status &&
                    validatedCertificatePrintStatus.ReasonForChange == certificateBatchLog.ReasonForChange;

                if (!duplicateUpdate)
                {
                    // the actual date of a certificate print status change is not held with the certificate, which holds when
                    // it was notified in it's updatedAt property so fetch the date from the certificate batch log instead
                    var certificatePrintStatusAt = CertificateStatus.HasPrintNotificateStatus(certificate.Status)
                        ? certificateBatchLog?.StatusAt
                        : null;

                    // we are being notified of status changes that took place in the past so the certificate status should only be updated
                    // when the certificate is still in the same batch and no new updates have been made more recently than the status change
                    var updateCertificate = validatedCertificatePrintStatus.BatchNumber == certificate.BatchNumber &&
                                            validatedCertificatePrintStatus.StatusAt > (certificatePrintStatusAt ?? certificate.LatestChange().Value) &&
                                            certificate.Status != CertificateStatus.Deleted;

                    var updateCertificateBatchLog = validatedCertificatePrintStatus.StatusAt >= certificateBatchLog.StatusAt;

                    await _certificateRepository.UpdatePrintStatus(
                        certificate,
                        certificateBatchLog.BatchNumber,
                        validatedCertificatePrintStatus.Status,
                        validatedCertificatePrintStatus.StatusAt,
                        validatedCertificatePrintStatus.ReasonForChange,
                        updateCertificate,
                        updateCertificateBatchLog);

                    if (updateCertificate)
                    {
                        _logger.LogInformation($"Certificate {validatedCertificatePrintStatus.CertificateReference} updated to status {validatedCertificatePrintStatus.Status} in batch {validatedCertificatePrintStatus.BatchNumber}");
                    }
                    else
                    {
                        _logger.LogInformation($"Certificate {validatedCertificatePrintStatus.CertificateReference} not updated to status {validatedCertificatePrintStatus.Status} in batch {validatedCertificatePrintStatus.BatchNumber} because it was not the latest change");
                    }
                }
                else
                {
                    _logger.LogInformation($"Certificate {validatedCertificatePrintStatus.CertificateReference} not updated to status {validatedCertificatePrintStatus.Status} in batch {validatedCertificatePrintStatus.BatchNumber} because it was a duplicate update");
                }
            }

            return(validationResult);
        }
Beispiel #4
0
        public async Task <ValidationResponse> Handle(CertificatePrintStatusUpdateRequest request, CancellationToken cancellationToken)
        {
            var validationResult = new ValidationResponse();

            var validatedCertificatePrintStatus = await Validate(request, validationResult);

            if (validatedCertificatePrintStatus != null)
            {
                var certificate = await _certificateRepository.GetCertificate(validatedCertificatePrintStatus.CertificateReference);

                if (certificate == null)
                {
                    validationResult.Errors.Add(
                        new ValidationErrorDetail(
                            "CertificatePrintStatuses",
                            $"The certificate reference {validatedCertificatePrintStatus.CertificateReference} was not found.",
                            ValidationStatusCode.NotFound));

                    return(validationResult);
                }

                var certificateBatchLog = await _certificateBatchLogRepository.GetCertificateBatchLog(validatedCertificatePrintStatus.CertificateReference, validatedCertificatePrintStatus.BatchNumber);

                if (certificateBatchLog == null)
                {
                    validationResult.Errors.Add(
                        new ValidationErrorDetail(
                            "CertificatePrintStatuses",
                            $"Certificate {validatedCertificatePrintStatus.CertificateReference} not printed in batch {validatedCertificatePrintStatus.BatchNumber}.",
                            ValidationStatusCode.NotFound));

                    return(validationResult);
                }

                if (validatedCertificatePrintStatus.StatusAt < certificateBatchLog.StatusAt)
                {
                    validationResult.Errors.Add(
                        new ValidationErrorDetail(
                            "StatusChangedDateTime",
                            $"Certificate {validatedCertificatePrintStatus.CertificateReference} {validatedCertificatePrintStatus.Status} at {validatedCertificatePrintStatus.StatusAt} is earlier than {certificateBatchLog.Status} at {certificateBatchLog.StatusAt}.",
                            ValidationStatusCode.Warning));
                }

                // use the actual print notification datetime for certificates which currently have a print notification status
                var certificatePrintStatusAt = CertificateStatus.HasPrintNotificateStatus(certificate.Status)
                    ? certificateBatchLog?.StatusAt
                    : null;

                // the certificate status should not be overwritten when it has been sent to printer or reprinted, has a more recent
                // changed datetime than the actual print notification datetime or when it has been deleted
                var isLatestChange = validatedCertificatePrintStatus.BatchNumber == certificate.BatchNumber &&
                                     validatedCertificatePrintStatus.StatusAt > (certificatePrintStatusAt ?? certificate.LatestChange().Value) &&
                                     certificate.Status != CertificateStatus.Deleted;

                await _certificateRepository.UpdatePrintStatus(
                    certificate,
                    validatedCertificatePrintStatus.BatchNumber,
                    validatedCertificatePrintStatus.Status,
                    validatedCertificatePrintStatus.StatusAt,
                    validatedCertificatePrintStatus.ReasonForChange,
                    isLatestChange);

                if (isLatestChange)
                {
                    _logger.LogInformation($"Certificate {validatedCertificatePrintStatus.CertificateReference} updated to status {validatedCertificatePrintStatus.Status} in batch {validatedCertificatePrintStatus.BatchNumber}");
                }
                else
                {
                    _logger.LogInformation($"Certificate {validatedCertificatePrintStatus.CertificateReference} not updated to status {validatedCertificatePrintStatus.Status} in batch {validatedCertificatePrintStatus.BatchNumber} because it was not the latest change");
                }
            }

            return(validationResult);
        }