AVS-Carton-Shipment-Verifier/Repositories/CartonVerificationRepositor...

103 lines
4.1 KiB
C#

using System.Text.RegularExpressions;
using AVSCartonShipmentVerifier.Configuration;
using AVSCartonShipmentVerifier.Data;
using Microsoft.Extensions.Options;
using MySqlConnector;
namespace AVSCartonShipmentVerifier.Repositories;
public sealed class CartonVerificationRepository(
IVerificationDbConnectionFactory connectionFactory,
IOptions<CartonVerificationOptions> options) : ICartonVerificationRepository
{
private static readonly Regex SqlIdentifierRegex = new("^[A-Za-z_][A-Za-z0-9_]*$", RegexOptions.Compiled);
private readonly IVerificationDbConnectionFactory _connectionFactory = connectionFactory;
private readonly CartonVerificationOptions _options = options.Value;
public async Task<CartonVerificationStatus> GetCartonStatusByUniqueNumberAsync(string uniqueNumber, CancellationToken cancellationToken = default)
{
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(cancellationToken);
await using var command = connection.CreateCommand();
command.CommandText = $"""
SELECT {QuoteIdentifier(_options.MovedToWarehouseColumnName)}
FROM {QuoteIdentifier(_options.TableName)}
WHERE {QuoteIdentifier(_options.QrColumnName)} = @uniqueNumber
LIMIT 1;
""";
command.Parameters.AddWithValue("@uniqueNumber", uniqueNumber);
var result = await command.ExecuteScalarAsync(cancellationToken);
if (result is null || result is DBNull)
{
return CartonVerificationStatus.NotFound;
}
var moved = Convert.ToInt32(result);
return moved != 0 ? CartonVerificationStatus.AlreadyTransferred : CartonVerificationStatus.PendingTransfer;
}
public async Task<bool> MarkShipmentVerifiedAsync(string uniqueNumber, CancellationToken cancellationToken = default)
{
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(cancellationToken);
await using var command = connection.CreateCommand();
command.CommandText = $"""
UPDATE {QuoteIdentifier(_options.TableName)}
SET {QuoteIdentifier(_options.MovedToWarehouseColumnName)} = 1
WHERE {QuoteIdentifier(_options.QrColumnName)} = @uniqueNumber
AND {QuoteIdentifier(_options.MovedToWarehouseColumnName)} = 0;
""";
command.Parameters.AddWithValue("@uniqueNumber", uniqueNumber);
var affectedRows = await command.ExecuteNonQueryAsync(cancellationToken);
return affectedRows > 0;
}
public async Task<int> GetAvailableCartonCountAsync(CancellationToken cancellationToken = default)
{
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(cancellationToken);
await using var command = connection.CreateCommand();
command.CommandText = $"""
SELECT COUNT(*)
FROM {QuoteIdentifier(_options.TableName)}
WHERE {QuoteIdentifier(_options.MovedToWarehouseColumnName)} = 0;
""";
var result = await command.ExecuteScalarAsync(cancellationToken);
return Convert.ToInt32(result);
}
public async Task<int> GetTotalMovedCartonCountAsync(CancellationToken cancellationToken = default)
{
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(cancellationToken);
await using var command = connection.CreateCommand();
command.CommandText = $"""
SELECT COUNT(*)
FROM {QuoteIdentifier(_options.TableName)}
WHERE {QuoteIdentifier(_options.MovedToWarehouseColumnName)} = 1;
""";
var result = await command.ExecuteScalarAsync(cancellationToken);
return Convert.ToInt32(result);
}
private static string QuoteIdentifier(string identifier)
{
if (!SqlIdentifierRegex.IsMatch(identifier))
{
throw new InvalidOperationException($"Invalid SQL identifier configured: '{identifier}'.");
}
return $"`{identifier}`";
}
}