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); }