103 lines
4.1 KiB
C#
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}`";
|
|
}
|
|
}
|
|
|