294 lines
9.8 KiB
C#
294 lines
9.8 KiB
C#
using System.Globalization;
|
|
using System.Text;
|
|
|
|
namespace line_gestao_api.Services;
|
|
|
|
internal static class MveAuditNormalization
|
|
{
|
|
public static string NormalizeHeader(string? value)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
var normalized = value.Trim().ToUpperInvariant().Normalize(NormalizationForm.FormD);
|
|
var builder = new StringBuilder(normalized.Length);
|
|
foreach (var ch in normalized)
|
|
{
|
|
if (CharUnicodeInfo.GetUnicodeCategory(ch) != UnicodeCategory.NonSpacingMark)
|
|
{
|
|
builder.Append(ch);
|
|
}
|
|
}
|
|
|
|
return builder.ToString()
|
|
.Replace("\u00A0", " ")
|
|
.Trim();
|
|
}
|
|
|
|
public static string CleanTextValue(string? value, bool removeSingleQuotes = true)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
var cleaned = value
|
|
.Replace("\u00A0", " ")
|
|
.Replace("\t", " ")
|
|
.Replace("\r", " ")
|
|
.Replace("\n", " ")
|
|
.Trim();
|
|
|
|
if (removeSingleQuotes)
|
|
{
|
|
cleaned = cleaned.Replace("'", string.Empty);
|
|
}
|
|
|
|
while (cleaned.Contains(" ", StringComparison.Ordinal))
|
|
{
|
|
cleaned = cleaned.Replace(" ", " ", StringComparison.Ordinal);
|
|
}
|
|
|
|
return cleaned.Trim();
|
|
}
|
|
|
|
public static string OnlyDigits(string? value)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
var builder = new StringBuilder(value.Length);
|
|
foreach (var ch in value)
|
|
{
|
|
if (char.IsDigit(ch))
|
|
{
|
|
builder.Append(ch);
|
|
}
|
|
}
|
|
|
|
return builder.ToString();
|
|
}
|
|
|
|
public static string? NullIfEmptyDigits(string? value)
|
|
{
|
|
var digits = OnlyDigits(value);
|
|
return string.IsNullOrWhiteSpace(digits) ? null : digits;
|
|
}
|
|
|
|
public static string NormalizeComparableText(string? value)
|
|
{
|
|
var cleaned = CleanTextValue(value);
|
|
if (string.IsNullOrWhiteSpace(cleaned))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
return NormalizeHeader(cleaned)
|
|
.Replace(" ", " ", StringComparison.Ordinal)
|
|
.Trim();
|
|
}
|
|
|
|
public static string NormalizeAccountLike(string? value)
|
|
{
|
|
var digits = OnlyDigits(value);
|
|
if (!string.IsNullOrWhiteSpace(digits))
|
|
{
|
|
return digits;
|
|
}
|
|
|
|
return NormalizeComparableText(value);
|
|
}
|
|
|
|
public static DateTime? ParseDateValue(string? rawValue)
|
|
{
|
|
var cleaned = CleanTextValue(rawValue);
|
|
if (string.IsNullOrWhiteSpace(cleaned))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (double.TryParse(
|
|
cleaned.Replace(",", ".", StringComparison.Ordinal),
|
|
NumberStyles.Float,
|
|
CultureInfo.InvariantCulture,
|
|
out var oaValue) &&
|
|
oaValue > 10_000 &&
|
|
oaValue < 90_000)
|
|
{
|
|
try
|
|
{
|
|
return ToUtcDateOnly(DateTime.FromOADate(oaValue));
|
|
}
|
|
catch
|
|
{
|
|
// segue para os demais formatos
|
|
}
|
|
}
|
|
|
|
var formats = new[]
|
|
{
|
|
"dd/MM/yyyy",
|
|
"d/M/yyyy",
|
|
"dd/MM/yy",
|
|
"d/M/yy",
|
|
"yyyy-MM-dd",
|
|
"dd-MM-yyyy",
|
|
"d-M-yyyy",
|
|
"yyyyMMdd"
|
|
};
|
|
|
|
foreach (var format in formats)
|
|
{
|
|
if (DateTime.TryParseExact(
|
|
cleaned,
|
|
format,
|
|
CultureInfo.InvariantCulture,
|
|
DateTimeStyles.None,
|
|
out var exact))
|
|
{
|
|
return ToUtcDateOnly(exact);
|
|
}
|
|
}
|
|
|
|
if (DateTime.TryParse(cleaned, new CultureInfo("pt-BR"), DateTimeStyles.None, out var parsedBr))
|
|
{
|
|
return ToUtcDateOnly(parsedBr);
|
|
}
|
|
|
|
if (DateTime.TryParse(cleaned, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedInvariant))
|
|
{
|
|
return ToUtcDateOnly(parsedInvariant);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static DateTime ToUtcDateOnly(DateTime date)
|
|
{
|
|
return new DateTime(date.Year, date.Month, date.Day, 12, 0, 0, DateTimeKind.Utc);
|
|
}
|
|
|
|
public static string FormatDate(DateTime? value)
|
|
{
|
|
return value.HasValue ? value.Value.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture) : string.Empty;
|
|
}
|
|
|
|
public static MveNormalizedStatus NormalizeReportStatus(string? rawValue)
|
|
{
|
|
var displayValue = CleanTextValue(rawValue);
|
|
if (string.IsNullOrWhiteSpace(displayValue))
|
|
{
|
|
return new MveNormalizedStatus(string.Empty, string.Empty, false);
|
|
}
|
|
|
|
var headSegment = NormalizeComparableText(displayValue.Split(':', 2)[0])
|
|
.Replace("/", " ", StringComparison.Ordinal)
|
|
.Replace("-", " ", StringComparison.Ordinal)
|
|
.Replace(".", " ", StringComparison.Ordinal)
|
|
.Replace("(", " ", StringComparison.Ordinal)
|
|
.Replace(")", " ", StringComparison.Ordinal)
|
|
.Replace(" ", " ", StringComparison.Ordinal)
|
|
.Trim();
|
|
|
|
var canonical = NormalizeComparableText(displayValue)
|
|
.Replace("/", " ", StringComparison.Ordinal)
|
|
.Replace("-", " ", StringComparison.Ordinal)
|
|
.Replace(".", " ", StringComparison.Ordinal)
|
|
.Replace("(", " ", StringComparison.Ordinal)
|
|
.Replace(")", " ", StringComparison.Ordinal)
|
|
.Replace(" ", " ", StringComparison.Ordinal)
|
|
.Trim();
|
|
|
|
var key = headSegment switch
|
|
{
|
|
var text when text.Contains("ATIVO", StringComparison.Ordinal) || text == "ATIVA" => "ATIVO",
|
|
var text when text.Contains("BLOQUEIO PARCIAL", StringComparison.Ordinal) => "BLOQUEIO_PERDA_ROUBO",
|
|
var text when text.Contains("CANCEL", StringComparison.Ordinal) => "BLOQUEIO_120_DIAS",
|
|
var text when text.Contains("SUSPENS", StringComparison.Ordinal) => "SUSPENSO",
|
|
var text when text.Contains("PENDENTE", StringComparison.Ordinal) &&
|
|
text.Contains("TROCA", StringComparison.Ordinal) &&
|
|
text.Contains("NUMERO", StringComparison.Ordinal) => "PENDENTE_TROCA_NUMERO",
|
|
var text when text.Contains("PERDA", StringComparison.Ordinal) || text.Contains("ROUBO", StringComparison.Ordinal) => "BLOQUEIO_PERDA_ROUBO",
|
|
var text when text.Contains("BLOQUEIO", StringComparison.Ordinal) && text.Contains("120", StringComparison.Ordinal) => "BLOQUEIO_120_DIAS",
|
|
_ => canonical.Replace(" ", "_", StringComparison.Ordinal)
|
|
};
|
|
|
|
var recognized = key is
|
|
"ATIVO" or
|
|
"BLOQUEIO_PERDA_ROUBO" or
|
|
"BLOQUEIO_120_DIAS" or
|
|
"SUSPENSO" or
|
|
"PENDENTE_TROCA_NUMERO";
|
|
|
|
return new MveNormalizedStatus(displayValue, key, recognized);
|
|
}
|
|
|
|
public static MveNormalizedStatus NormalizeSystemStatus(string? rawValue)
|
|
{
|
|
var displayValue = CleanTextValue(rawValue);
|
|
if (string.IsNullOrWhiteSpace(displayValue))
|
|
{
|
|
return new MveNormalizedStatus(string.Empty, string.Empty, false);
|
|
}
|
|
|
|
var canonical = NormalizeComparableText(displayValue)
|
|
.Replace("/", " ", StringComparison.Ordinal)
|
|
.Replace("-", " ", StringComparison.Ordinal)
|
|
.Replace(".", " ", StringComparison.Ordinal)
|
|
.Replace(":", " ", StringComparison.Ordinal)
|
|
.Replace("(", " ", StringComparison.Ordinal)
|
|
.Replace(")", " ", StringComparison.Ordinal)
|
|
.Replace(" ", " ", StringComparison.Ordinal)
|
|
.Trim();
|
|
|
|
var key = canonical switch
|
|
{
|
|
var text when text.Contains("ATIVO", StringComparison.Ordinal) || text == "ATIVA" => "ATIVO",
|
|
var text when text.Contains("PERDA", StringComparison.Ordinal) || text.Contains("ROUBO", StringComparison.Ordinal) => "BLOQUEIO_PERDA_ROUBO",
|
|
var text when text.Contains("BLOQUEIO PARCIAL", StringComparison.Ordinal) => "BLOQUEIO_PERDA_ROUBO",
|
|
var text when text.Contains("BLOQUEIO", StringComparison.Ordinal) && text.Contains("120", StringComparison.Ordinal) => "BLOQUEIO_120_DIAS",
|
|
var text when text.Contains("CANCEL", StringComparison.Ordinal) => "CANCELADO",
|
|
var text when text.Contains("SUSPENS", StringComparison.Ordinal) => "SUSPENSO",
|
|
var text when text.Contains("PENDENTE", StringComparison.Ordinal) &&
|
|
text.Contains("TROCA", StringComparison.Ordinal) &&
|
|
text.Contains("NUMERO", StringComparison.Ordinal) => "PENDENTE_TROCA_NUMERO",
|
|
_ => canonical.Replace(" ", "_", StringComparison.Ordinal)
|
|
};
|
|
|
|
var recognized = key is
|
|
"ATIVO" or
|
|
"BLOQUEIO_PERDA_ROUBO" or
|
|
"BLOQUEIO_120_DIAS" or
|
|
"CANCELADO" or
|
|
"SUSPENSO" or
|
|
"PENDENTE_TROCA_NUMERO";
|
|
|
|
return new MveNormalizedStatus(displayValue, key, recognized);
|
|
}
|
|
|
|
public static MveNormalizedStatus NormalizeStatus(string? rawValue)
|
|
{
|
|
return NormalizeSystemStatus(rawValue);
|
|
}
|
|
|
|
public static string NormalizeStatusForSystem(string? rawValue)
|
|
{
|
|
var normalized = NormalizeReportStatus(rawValue);
|
|
return normalized.Key switch
|
|
{
|
|
"ATIVO" => "ATIVO",
|
|
"BLOQUEIO_PERDA_ROUBO" => "BLOQUEIO PERDA/ROUBO",
|
|
"BLOQUEIO_120_DIAS" => "BLOQUEIO 120 DIAS",
|
|
"SUSPENSO" => "SUSPENSO",
|
|
"PENDENTE_TROCA_NUMERO" => "PENDENTE TROCA NUMERO",
|
|
_ => normalized.DisplayValue
|
|
};
|
|
}
|
|
}
|
|
|
|
internal sealed record MveNormalizedStatus(string DisplayValue, string Key, bool Recognized);
|