261 lines
9.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|