line-gestao-api/Services/OperadoraContaResolver.cs

261 lines
9.7 KiB
C#

using System.Globalization;
using System.Text;
using line_gestao_api.Dtos;
using line_gestao_api.Models;
using Microsoft.EntityFrameworkCore;
namespace line_gestao_api.Services
{
public sealed record OperadoraContaContext(string Operadora, string Empresa, string? VivoEmpresaGrupo = null);
public static class OperadoraContaResolver
{
private const string OperadoraVivo = "VIVO";
private const string OperadoraClaro = "CLARO";
private const string OperadoraTim = "TIM";
private const string OperadoraOutra = "OUTRA";
private const string EmpresaVivoMacrophony = "VIVO MACROPHONY";
private const string EmpresaVivoLineMovel = "VIVO LINE MÓVEL";
private const string EmpresaClaroLineMovel = "CLARO LINE MÓVEL";
private const string EmpresaTimLineMovel = "TIM LINE MÓVEL";
private static readonly IReadOnlyList<AccountCompanyDto> CompanyRules = new List<AccountCompanyDto>
{
new()
{
Empresa = EmpresaClaroLineMovel,
Contas = new List<string> { "172593311", "172593840", "187890982" }
},
new()
{
Empresa = EmpresaVivoMacrophony,
Contas = new List<string>
{
"0430237019",
"0437488125",
"0449508564",
"0454371844",
"455371844",
"460161507"
}
},
new()
{
Empresa = EmpresaVivoLineMovel,
Contas = new List<string> { "0435288088" }
},
new()
{
Empresa = EmpresaTimLineMovel,
Contas = new List<string> { "TIM" }
}
};
private static readonly string[] VivoContaFilters = BuildContaFilterSet(EmpresaVivoMacrophony, EmpresaVivoLineMovel);
private static readonly string[] ClaroContaFilters = BuildContaFilterSet(EmpresaClaroLineMovel);
private static readonly string[] TimContaFilters = BuildContaFilterSet(EmpresaTimLineMovel);
private static readonly Dictionary<string, string> EmpresaByConta = BuildEmpresaByConta();
public static List<AccountCompanyDto> GetAccountCompanies()
{
return CompanyRules
.Select(x => new AccountCompanyDto
{
Empresa = x.Empresa,
Contas = x.Contas.ToList()
})
.ToList();
}
public static List<string> GetAccountsByEmpresa(string? empresa)
{
if (string.IsNullOrWhiteSpace(empresa)) return new List<string>();
var target = NormalizeToken(empresa);
if (string.IsNullOrWhiteSpace(target)) return new List<string>();
return CompanyRules
.FirstOrDefault(x => NormalizeToken(x.Empresa) == target)
?.Contas
?.ToList()
?? new List<string>();
}
public static OperadoraContaContext Resolve(string? conta)
{
var contaRaw = (conta ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(contaRaw))
{
return new OperadoraContaContext(OperadoraOutra, string.Empty, null);
}
var normalizedConta = NormalizeConta(contaRaw);
if (!string.IsNullOrWhiteSpace(normalizedConta) && EmpresaByConta.TryGetValue(normalizedConta, out var empresaDeterministica))
{
return BuildContextByEmpresa(empresaDeterministica);
}
var token = NormalizeToken(contaRaw);
if (token.Contains("TIM", StringComparison.Ordinal))
{
return BuildContextByEmpresa(EmpresaTimLineMovel);
}
if (token.Contains("CLARO", StringComparison.Ordinal))
{
return BuildContextByEmpresa(EmpresaClaroLineMovel);
}
if (token.Contains("MACROPHONY", StringComparison.Ordinal))
{
return BuildContextByEmpresa(EmpresaVivoMacrophony);
}
if (token.Contains("VIVO", StringComparison.Ordinal))
{
return BuildContextByEmpresa(EmpresaVivoLineMovel);
}
return new OperadoraContaContext(OperadoraOutra, string.Empty, null);
}
public static IQueryable<MobileLine> ApplyOperadoraFilter(IQueryable<MobileLine> query, string? operadora)
{
var token = NormalizeToken(operadora);
if (string.IsNullOrWhiteSpace(token) || token == "TODOS" || token == "ALL")
{
return query;
}
return token switch
{
OperadoraVivo => query.Where(x =>
(x.Conta != null && VivoContaFilters.Contains(x.Conta.Trim()))
|| EF.Functions.ILike((x.Conta ?? string.Empty).Trim(), "%VIVO%")
|| EF.Functions.ILike((x.Conta ?? string.Empty).Trim(), "%MACROPHONY%")),
OperadoraClaro => query.Where(x =>
(x.Conta != null && ClaroContaFilters.Contains(x.Conta.Trim()))
|| EF.Functions.ILike((x.Conta ?? string.Empty).Trim(), "%CLARO%")),
OperadoraTim => query.Where(x =>
(x.Conta != null && TimContaFilters.Contains(x.Conta.Trim()))
|| EF.Functions.ILike((x.Conta ?? string.Empty).Trim(), "%TIM%")),
_ => query
};
}
public static string NormalizeConta(string? conta)
{
var raw = (conta ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(raw)) return string.Empty;
if (raw.All(char.IsDigit))
{
var noLeadingZero = raw.TrimStart('0');
return string.IsNullOrWhiteSpace(noLeadingZero) ? "0" : noLeadingZero;
}
return RemoveDiacritics(raw).ToUpperInvariant();
}
private static OperadoraContaContext BuildContextByEmpresa(string empresa)
{
var token = NormalizeToken(empresa);
var operadora = token.Contains("CLARO", StringComparison.Ordinal)
? OperadoraClaro
: token.Contains("TIM", StringComparison.Ordinal)
? OperadoraTim
: token.Contains("VIVO", StringComparison.Ordinal) || token.Contains("MACROPHONY", StringComparison.Ordinal)
? OperadoraVivo
: OperadoraOutra;
var vivoGrupo = operadora == OperadoraVivo
? token.Contains("MACROPHONY", StringComparison.Ordinal)
? "MACROPHONY"
: token.Contains("LINEMOVEL", StringComparison.Ordinal)
? "LINE MOVEL"
: null
: null;
return new OperadoraContaContext(operadora, empresa, vivoGrupo);
}
private static Dictionary<string, string> BuildEmpresaByConta()
{
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var group in CompanyRules)
{
foreach (var conta in group.Contas ?? new List<string>())
{
var normalized = NormalizeConta(conta);
if (string.IsNullOrWhiteSpace(normalized)) continue;
map[normalized] = group.Empresa;
}
}
return map;
}
private static string[] BuildContaFilterSet(params string[] empresas)
{
var empresaTokens = new HashSet<string>(empresas.Select(NormalizeToken), StringComparer.OrdinalIgnoreCase);
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var group in CompanyRules)
{
if (!empresaTokens.Contains(NormalizeToken(group.Empresa))) continue;
foreach (var conta in group.Contas ?? new List<string>())
{
var trimmed = (conta ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(trimmed)) continue;
set.Add(trimmed);
if (trimmed.All(char.IsDigit))
{
var noLeading = trimmed.TrimStart('0');
if (!string.IsNullOrWhiteSpace(noLeading))
{
set.Add(noLeading);
}
}
}
}
return set.ToArray();
}
private static string NormalizeToken(string? value)
{
if (string.IsNullOrWhiteSpace(value)) return string.Empty;
var raw = RemoveDiacritics(value);
var sb = new StringBuilder(raw.Length);
foreach (var ch in raw)
{
if (char.IsLetterOrDigit(ch)) sb.Append(char.ToUpperInvariant(ch));
}
return sb.ToString();
}
private static string RemoveDiacritics(string value)
{
if (string.IsNullOrWhiteSpace(value)) return string.Empty;
var normalized = value.Normalize(NormalizationForm.FormD);
var sb = new StringBuilder(normalized.Length);
foreach (var c in normalized)
{
var category = CharUnicodeInfo.GetUnicodeCategory(c);
if (category != UnicodeCategory.NonSpacingMark)
{
sb.Append(c);
}
}
return sb.ToString().Normalize(NormalizationForm.FormC);
}
}
}