AVS-Carton-Shipment-Verifier/Services/ShipmentVerificationService.cs

113 lines
3.9 KiB
C#

using AVSCartonShipmentVerifier.DTOs;
using AVSCartonShipmentVerifier.Repositories;
namespace AVSCartonShipmentVerifier.Services;
public sealed class ShipmentVerificationService(
ICartonVerificationRepository repository,
IScanHistoryStore historyStore,
ILogger<ShipmentVerificationService> logger) : IShipmentVerificationService
{
private readonly ICartonVerificationRepository _repository = repository;
private readonly IScanHistoryStore _historyStore = historyStore;
private readonly ILogger<ShipmentVerificationService> _logger = logger;
public async Task<VerificationResultDto> VerifyQrAsync(string rawQrValue, CancellationToken cancellationToken = default)
{
var parseResult = TryParseQr(rawQrValue);
if (!parseResult.IsValid)
{
return BuildFailure(parseResult.ErrorMessage);
}
var nowUtc = DateTime.UtcNow;
bool exists;
try
{
exists = await _repository.UniqueNumberExistsAsync(parseResult.UniqueNumber, cancellationToken);
}
catch (Exception exception)
{
_logger.LogError(exception, "Verification lookup failed for unique number {UniqueNumber}.", parseResult.UniqueNumber);
return BuildFailure("Unable to verify QR at the moment. Please try again.");
}
if (!exists)
{
var missingResult = new VerificationResultDto
{
ModelNumber = parseResult.ModelNumber,
UniqueNumber = parseResult.UniqueNumber,
RawQrValue = rawQrValue,
ExistsInSystem = false,
ShipmentMarked = false,
Message = "Shipment not completed. Unique number was not found.",
ProcessedAtUtc = nowUtc
};
_historyStore.Add(ToScannedRecord(missingResult));
return missingResult;
}
var result = new VerificationResultDto
{
ModelNumber = parseResult.ModelNumber,
UniqueNumber = parseResult.UniqueNumber,
RawQrValue = rawQrValue,
ExistsInSystem = true,
ShipmentMarked = true,
Message = "Record found in carton verification log.",
ProcessedAtUtc = nowUtc
};
_historyStore.Add(ToScannedRecord(result));
return result;
}
private static (bool IsValid, string ModelNumber, string UniqueNumber, string ErrorMessage) TryParseQr(string rawQrValue)
{
if (string.IsNullOrWhiteSpace(rawQrValue))
{
return (false, string.Empty, string.Empty, "QR value is required.");
}
if (!rawQrValue.Contains(';'))
{
return (false, string.Empty, string.Empty, "Invalid QR format. Missing ';' separator. Use modelnumber;uniquenumber.");
}
var parts = rawQrValue.Split(';', StringSplitOptions.TrimEntries);
if (parts.Length != 2)
{
return (false, string.Empty, string.Empty, "Invalid QR format. Use modelnumber;uniquenumber.");
}
var modelNumber = parts[0];
var uniqueNumber = parts[1];
if (string.IsNullOrWhiteSpace(uniqueNumber))
{
return (false, modelNumber, string.Empty, "Invalid QR format. Unique number is missing after ';'.");
}
return (true, modelNumber, uniqueNumber, string.Empty);
}
private static VerificationResultDto BuildFailure(string message) => new()
{
Message = message,
ExistsInSystem = false,
ShipmentMarked = false,
ProcessedAtUtc = DateTime.UtcNow
};
private static ScannedRecordDto ToScannedRecord(VerificationResultDto result) => new()
{
ModelNumber = result.ModelNumber,
UniqueNumber = result.UniqueNumber,
ExistsInSystem = result.ExistsInSystem,
ShipmentMarked = result.ShipmentMarked,
ProcessedAtUtc = result.ProcessedAtUtc
};
}