Aplicando filtros por operadora e endpoints para filtragem
This commit is contained in:
parent
64ffb9f2e5
commit
78f403105c
|
|
@ -18,9 +18,9 @@ namespace line_gestao_api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("insights")]
|
[HttpGet("insights")]
|
||||||
public async Task<ActionResult<GeralDashboardInsightsDto>> GetInsights()
|
public async Task<ActionResult<GeralDashboardInsightsDto>> GetInsights([FromQuery] string? operadora = null)
|
||||||
{
|
{
|
||||||
var dto = await _service.GetInsightsAsync();
|
var dto = await _service.GetInsightsAsync(operadora);
|
||||||
return Ok(dto);
|
return Ok(dto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,29 +33,6 @@ namespace line_gestao_api.Controllers
|
||||||
private readonly SpreadsheetImportAuditService _spreadsheetImportAuditService;
|
private readonly SpreadsheetImportAuditService _spreadsheetImportAuditService;
|
||||||
private readonly string _aparelhoAttachmentsRootPath;
|
private readonly string _aparelhoAttachmentsRootPath;
|
||||||
private static readonly FileExtensionContentTypeProvider FileContentTypeProvider = new();
|
private static readonly FileExtensionContentTypeProvider FileContentTypeProvider = new();
|
||||||
private static readonly List<AccountCompanyDto> AccountCompanies = new()
|
|
||||||
{
|
|
||||||
new AccountCompanyDto
|
|
||||||
{
|
|
||||||
Empresa = "CLARO LINE MÓVEL",
|
|
||||||
Contas = new List<string> { "172593311", "172593840" }
|
|
||||||
},
|
|
||||||
new AccountCompanyDto
|
|
||||||
{
|
|
||||||
Empresa = "VIVO MACROPHONY",
|
|
||||||
Contas = new List<string> { "0430237019", "0437488125", "0449508564", "0454371844" }
|
|
||||||
},
|
|
||||||
new AccountCompanyDto
|
|
||||||
{
|
|
||||||
Empresa = "VIVO LINE MÓVEL",
|
|
||||||
Contas = new List<string> { "0435288088" }
|
|
||||||
},
|
|
||||||
new AccountCompanyDto
|
|
||||||
{
|
|
||||||
Empresa = "TIM LINE MÓVEL",
|
|
||||||
Contas = new List<string> { "0072046192" }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public LinesController(
|
public LinesController(
|
||||||
AppDbContext db,
|
AppDbContext db,
|
||||||
|
|
@ -390,31 +367,14 @@ namespace line_gestao_api.Controllers
|
||||||
[HttpGet("account-companies")]
|
[HttpGet("account-companies")]
|
||||||
public ActionResult<List<AccountCompanyDto>> GetAccountCompanies()
|
public ActionResult<List<AccountCompanyDto>> GetAccountCompanies()
|
||||||
{
|
{
|
||||||
var items = AccountCompanies
|
var items = OperadoraContaResolver.GetAccountCompanies();
|
||||||
.Select(x => new AccountCompanyDto
|
|
||||||
{
|
|
||||||
Empresa = x.Empresa,
|
|
||||||
Contas = x.Contas.ToList()
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
return Ok(items);
|
return Ok(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("accounts")]
|
[HttpGet("accounts")]
|
||||||
public ActionResult<List<string>> GetAccounts([FromQuery] string? empresa)
|
public ActionResult<List<string>> GetAccounts([FromQuery] string? empresa)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(empresa))
|
var contas = OperadoraContaResolver.GetAccountsByEmpresa(empresa);
|
||||||
return Ok(new List<string>());
|
|
||||||
|
|
||||||
var target = empresa.Trim();
|
|
||||||
|
|
||||||
var contas = AccountCompanies
|
|
||||||
.FirstOrDefault(x => string.Equals(x.Empresa, target, StringComparison.OrdinalIgnoreCase))
|
|
||||||
?.Contas
|
|
||||||
?.ToList()
|
|
||||||
?? new List<string>();
|
|
||||||
|
|
||||||
return Ok(contas);
|
return Ok(contas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -459,6 +419,7 @@ namespace line_gestao_api.Controllers
|
||||||
[FromQuery] string? search,
|
[FromQuery] string? search,
|
||||||
[FromQuery] string? skil,
|
[FromQuery] string? skil,
|
||||||
[FromQuery] string? client,
|
[FromQuery] string? client,
|
||||||
|
[FromQuery] string? operadora,
|
||||||
[FromQuery] string? additionalMode,
|
[FromQuery] string? additionalMode,
|
||||||
[FromQuery] string? additionalServices,
|
[FromQuery] string? additionalServices,
|
||||||
[FromQuery] int page = 1,
|
[FromQuery] int page = 1,
|
||||||
|
|
@ -491,6 +452,7 @@ namespace line_gestao_api.Controllers
|
||||||
q = ExcludeReservaContext(q);
|
q = ExcludeReservaContext(q);
|
||||||
|
|
||||||
q = ApplyAdditionalFilters(q, additionalMode, additionalServices);
|
q = ApplyAdditionalFilters(q, additionalMode, additionalServices);
|
||||||
|
q = OperadoraContaResolver.ApplyOperadoraFilter(q, operadora);
|
||||||
|
|
||||||
var sb = (sortBy ?? "item").Trim().ToLowerInvariant();
|
var sb = (sortBy ?? "item").Trim().ToLowerInvariant();
|
||||||
var desc = string.Equals((sortDir ?? "asc").Trim(), "desc", StringComparison.OrdinalIgnoreCase);
|
var desc = string.Equals((sortDir ?? "asc").Trim(), "desc", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
@ -545,6 +507,7 @@ namespace line_gestao_api.Controllers
|
||||||
line.Skil,
|
line.Skil,
|
||||||
line.Modalidade,
|
line.Modalidade,
|
||||||
line.VencConta,
|
line.VencConta,
|
||||||
|
line.FranquiaVivo,
|
||||||
line.FranquiaLine,
|
line.FranquiaLine,
|
||||||
line.GestaoVozDados,
|
line.GestaoVozDados,
|
||||||
line.Skeelo,
|
line.Skeelo,
|
||||||
|
|
@ -614,6 +577,7 @@ namespace line_gestao_api.Controllers
|
||||||
Skil = x.Skil,
|
Skil = x.Skil,
|
||||||
Modalidade = x.Modalidade,
|
Modalidade = x.Modalidade,
|
||||||
VencConta = x.VencConta,
|
VencConta = x.VencConta,
|
||||||
|
FranquiaVivo = x.FranquiaVivo,
|
||||||
FranquiaLine = x.FranquiaLine,
|
FranquiaLine = x.FranquiaLine,
|
||||||
GestaoVozDados = x.GestaoVozDados,
|
GestaoVozDados = x.GestaoVozDados,
|
||||||
Skeelo = x.Skeelo,
|
Skeelo = x.Skeelo,
|
||||||
|
|
@ -625,6 +589,8 @@ namespace line_gestao_api.Controllers
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
EnrichOperadoraContext(itemsReserva);
|
||||||
|
|
||||||
return Ok(new PagedResult<MobileLineListDto>
|
return Ok(new PagedResult<MobileLineListDto>
|
||||||
{
|
{
|
||||||
Page = page,
|
Page = page,
|
||||||
|
|
@ -687,6 +653,7 @@ namespace line_gestao_api.Controllers
|
||||||
Skil = x.Skil,
|
Skil = x.Skil,
|
||||||
Modalidade = x.Modalidade,
|
Modalidade = x.Modalidade,
|
||||||
VencConta = x.VencConta,
|
VencConta = x.VencConta,
|
||||||
|
FranquiaVivo = x.FranquiaVivo,
|
||||||
FranquiaLine = x.FranquiaLine,
|
FranquiaLine = x.FranquiaLine,
|
||||||
GestaoVozDados = x.GestaoVozDados,
|
GestaoVozDados = x.GestaoVozDados,
|
||||||
Skeelo = x.Skeelo,
|
Skeelo = x.Skeelo,
|
||||||
|
|
@ -698,6 +665,8 @@ namespace line_gestao_api.Controllers
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
EnrichOperadoraContext(items);
|
||||||
|
|
||||||
return Ok(new PagedResult<MobileLineListDto>
|
return Ok(new PagedResult<MobileLineListDto>
|
||||||
{
|
{
|
||||||
Page = page,
|
Page = page,
|
||||||
|
|
@ -5273,6 +5242,16 @@ namespace line_gestao_api.Controllers
|
||||||
return vigencia;
|
return vigencia;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EnrichOperadoraContext(IEnumerable<MobileLineListDto> items)
|
||||||
|
{
|
||||||
|
foreach (var item in items ?? Enumerable.Empty<MobileLineListDto>())
|
||||||
|
{
|
||||||
|
var context = OperadoraContaResolver.Resolve(item.Conta);
|
||||||
|
item.ContaEmpresa = context.Empresa;
|
||||||
|
item.Operadora = context.Operadora;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static MobileLineDetailDto ToDetailDto(MobileLine x, VigenciaLine? vigencia = null) => new()
|
private static MobileLineDetailDto ToDetailDto(MobileLine x, VigenciaLine? vigencia = null) => new()
|
||||||
{
|
{
|
||||||
Id = x.Id,
|
Id = x.Id,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using line_gestao_api.Data;
|
using line_gestao_api.Data;
|
||||||
using line_gestao_api.Dtos;
|
using line_gestao_api.Dtos;
|
||||||
|
using line_gestao_api.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
@ -19,7 +20,7 @@ namespace line_gestao_api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("dashboard")]
|
[HttpGet("dashboard")]
|
||||||
public async Task<ActionResult<RelatoriosDashboardDto>> GetDashboard()
|
public async Task<ActionResult<RelatoriosDashboardDto>> GetDashboard([FromQuery] string? operadora = null)
|
||||||
{
|
{
|
||||||
var todayUtcStart = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Utc);
|
var todayUtcStart = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Utc);
|
||||||
var tomorrowUtcStart = todayUtcStart.AddDays(1);
|
var tomorrowUtcStart = todayUtcStart.AddDays(1);
|
||||||
|
|
@ -31,32 +32,40 @@ namespace line_gestao_api.Controllers
|
||||||
// =========================
|
// =========================
|
||||||
// GERAL (MobileLines)
|
// GERAL (MobileLines)
|
||||||
// =========================
|
// =========================
|
||||||
var qLines = _db.MobileLines.AsNoTracking();
|
var qLines = OperadoraContaResolver.ApplyOperadoraFilter(_db.MobileLines.AsNoTracking(), operadora);
|
||||||
var qLinesWithClient = qLines.Where(x => x.Cliente != null && x.Cliente != "");
|
var qReserva = qLines.Where(x =>
|
||||||
|
EF.Functions.ILike((x.Usuario ?? "").Trim(), "RESERVA") ||
|
||||||
|
EF.Functions.ILike((x.Skil ?? "").Trim(), "RESERVA") ||
|
||||||
|
EF.Functions.ILike((x.Cliente ?? "").Trim(), "RESERVA"));
|
||||||
|
var qOperacionais = qLines.Where(x =>
|
||||||
|
!EF.Functions.ILike((x.Usuario ?? "").Trim(), "RESERVA") &&
|
||||||
|
!EF.Functions.ILike((x.Skil ?? "").Trim(), "RESERVA") &&
|
||||||
|
!EF.Functions.ILike((x.Cliente ?? "").Trim(), "RESERVA"));
|
||||||
|
var qOperacionaisWithClient = qOperacionais.Where(x => x.Cliente != null && x.Cliente != "");
|
||||||
|
|
||||||
var totalLinhas = await qLines.CountAsync();
|
var totalLinhas = await qLines.CountAsync();
|
||||||
|
|
||||||
var clientesUnicos = await qLines
|
var clientesUnicos = await qOperacionais
|
||||||
.Where(x => x.Cliente != null && x.Cliente != "")
|
.Where(x => x.Cliente != null && x.Cliente != "")
|
||||||
.Select(x => x.Cliente!)
|
.Select(x => x.Cliente!)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.CountAsync();
|
.CountAsync();
|
||||||
|
|
||||||
var ativos = await qLines.CountAsync(x =>
|
var ativos = await qOperacionais.CountAsync(x =>
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%ativo%"));
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%ativo%"));
|
||||||
|
|
||||||
var bloqueadosPerdaRoubo = await qLinesWithClient.CountAsync(x =>
|
var bloqueadosPerdaRoubo = await qOperacionaisWithClient.CountAsync(x =>
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") ||
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") ||
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%"));
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%"));
|
||||||
|
|
||||||
var bloqueados120Dias = await qLinesWithClient.CountAsync(x =>
|
var bloqueados120Dias = await qOperacionaisWithClient.CountAsync(x =>
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%bloque%") &&
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%bloque%") &&
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%120%") &&
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%120%") &&
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%dia%") &&
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%dia%") &&
|
||||||
!(EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") ||
|
!(EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") ||
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%")));
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%")));
|
||||||
|
|
||||||
var bloqueadosOutros = await qLinesWithClient.CountAsync(x =>
|
var bloqueadosOutros = await qOperacionaisWithClient.CountAsync(x =>
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%bloque%") &&
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%bloque%") &&
|
||||||
!(EF.Functions.ILike((x.Status ?? "").Trim(), "%120%") && EF.Functions.ILike((x.Status ?? "").Trim(), "%dia%")) &&
|
!(EF.Functions.ILike((x.Status ?? "").Trim(), "%120%") && EF.Functions.ILike((x.Status ?? "").Trim(), "%dia%")) &&
|
||||||
!(EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") || EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%"))
|
!(EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") || EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%"))
|
||||||
|
|
@ -64,16 +73,13 @@ namespace line_gestao_api.Controllers
|
||||||
|
|
||||||
// Regra do KPI "Bloqueadas" alinhada ao critério da página Geral:
|
// Regra do KPI "Bloqueadas" alinhada ao critério da página Geral:
|
||||||
// status contendo "bloque", "perda" ou "roubo".
|
// status contendo "bloque", "perda" ou "roubo".
|
||||||
var bloqueados = await qLinesWithClient.CountAsync(x =>
|
var bloqueados = await qOperacionaisWithClient.CountAsync(x =>
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%bloque%") ||
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%bloque%") ||
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") ||
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%perda%") ||
|
||||||
EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%"));
|
EF.Functions.ILike((x.Status ?? "").Trim(), "%roubo%"));
|
||||||
|
|
||||||
// Regra alinhada ao filtro "Reservas" da página Geral.
|
// Regra alinhada ao filtro "Reservas" da página Geral.
|
||||||
var reservas = await qLines.CountAsync(x =>
|
var reservas = await qReserva.CountAsync();
|
||||||
EF.Functions.ILike((x.Usuario ?? "").Trim(), "RESERVA") ||
|
|
||||||
EF.Functions.ILike((x.Skil ?? "").Trim(), "RESERVA") ||
|
|
||||||
EF.Functions.ILike((x.Cliente ?? "").Trim(), "RESERVA"));
|
|
||||||
|
|
||||||
var topClientes = await qLines
|
var topClientes = await qLines
|
||||||
.Where(x => x.Cliente != null && x.Cliente != "")
|
.Where(x => x.Cliente != null && x.Cliente != "")
|
||||||
|
|
@ -173,7 +179,16 @@ namespace line_gestao_api.Controllers
|
||||||
// =========================
|
// =========================
|
||||||
// USER DATA
|
// USER DATA
|
||||||
// =========================
|
// =========================
|
||||||
var qUserData = _db.UserDatas.AsNoTracking();
|
var qLineItems = qLines
|
||||||
|
.Where(x => x.Item > 0)
|
||||||
|
.Select(x => x.Item);
|
||||||
|
var qLineNumbers = qLines
|
||||||
|
.Where(x => x.Linha != null && x.Linha != "")
|
||||||
|
.Select(x => x.Linha!);
|
||||||
|
var qUserData = _db.UserDatas.AsNoTracking()
|
||||||
|
.Where(x =>
|
||||||
|
(x.Item > 0 && qLineItems.Contains(x.Item)) ||
|
||||||
|
(x.Linha != null && x.Linha != "" && qLineNumbers.Contains(x.Linha)));
|
||||||
|
|
||||||
var userDataRegistros = await qUserData.CountAsync();
|
var userDataRegistros = await qUserData.CountAsync();
|
||||||
var userDataComCpf = await qUserData.CountAsync(x => x.Cpf != null && x.Cpf != "");
|
var userDataComCpf = await qUserData.CountAsync(x => x.Cpf != null && x.Cpf != "");
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ namespace line_gestao_api.Dtos
|
||||||
{
|
{
|
||||||
public int QtdLinhas { get; set; }
|
public int QtdLinhas { get; set; }
|
||||||
public decimal TotalFranquiaGb { get; set; }
|
public decimal TotalFranquiaGb { get; set; }
|
||||||
|
public decimal TotalFranquiaLine { get; set; }
|
||||||
public decimal TotalBaseMensal { get; set; }
|
public decimal TotalBaseMensal { get; set; }
|
||||||
public decimal TotalAdicionaisMensal { get; set; }
|
public decimal TotalAdicionaisMensal { get; set; }
|
||||||
public decimal TotalGeralMensal { get; set; }
|
public decimal TotalGeralMensal { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@
|
||||||
public string? Skil { get; set; }
|
public string? Skil { get; set; }
|
||||||
public string? Modalidade { get; set; }
|
public string? Modalidade { get; set; }
|
||||||
public string? VencConta { get; set; }
|
public string? VencConta { get; set; }
|
||||||
|
public string? ContaEmpresa { get; set; }
|
||||||
|
public string? Operadora { get; set; }
|
||||||
|
public decimal? FranquiaVivo { get; set; }
|
||||||
public decimal? FranquiaLine { get; set; }
|
public decimal? FranquiaLine { get; set; }
|
||||||
|
|
||||||
// Campos para filtro deterministico de adicionais no frontend
|
// Campos para filtro deterministico de adicionais no frontend
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ namespace line_gestao_api.Models
|
||||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
// ✅ Navegação (1 MobileLine -> N Muregs)
|
|
||||||
public ICollection<MuregLine> Muregs { get; set; } = new List<MuregLine>();
|
public ICollection<MuregLine> Muregs { get; set; } = new List<MuregLine>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ namespace line_gestao_api.Services
|
||||||
_db = db;
|
_db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<GeralDashboardInsightsDto> GetInsightsAsync()
|
public async Task<GeralDashboardInsightsDto> GetInsightsAsync(string? operadora = null)
|
||||||
{
|
{
|
||||||
var qLines = _db.MobileLines.AsNoTracking();
|
var qLines = OperadoraContaResolver.ApplyOperadoraFilter(_db.MobileLines.AsNoTracking(), operadora);
|
||||||
|
|
||||||
var totals = await qLines
|
var totals = await qLines
|
||||||
.GroupBy(_ => 1)
|
.GroupBy(_ => 1)
|
||||||
|
|
@ -99,6 +99,7 @@ namespace line_gestao_api.Services
|
||||||
x.VivoGestaoDispositivo != null)
|
x.VivoGestaoDispositivo != null)
|
||||||
? (x.FranquiaVivo ?? 0m)
|
? (x.FranquiaVivo ?? 0m)
|
||||||
: 0m),
|
: 0m),
|
||||||
|
TotalFranquiaLine = g.Sum(x => x.FranquiaLine ?? 0m),
|
||||||
VivoAdicionaisTotal = g.Sum(x =>
|
VivoAdicionaisTotal = g.Sum(x =>
|
||||||
(x.ValorPlanoVivo != null ||
|
(x.ValorPlanoVivo != null ||
|
||||||
x.FranquiaVivo != null ||
|
x.FranquiaVivo != null ||
|
||||||
|
|
@ -653,6 +654,7 @@ namespace line_gestao_api.Services
|
||||||
{
|
{
|
||||||
QtdLinhas = totals.VivoLinhas,
|
QtdLinhas = totals.VivoLinhas,
|
||||||
TotalFranquiaGb = totals.VivoFranquiaTotalGb,
|
TotalFranquiaGb = totals.VivoFranquiaTotalGb,
|
||||||
|
TotalFranquiaLine = totals.TotalFranquiaLine,
|
||||||
TotalBaseMensal = totals.VivoBaseTotal,
|
TotalBaseMensal = totals.VivoBaseTotal,
|
||||||
TotalAdicionaisMensal = totals.VivoAdicionaisTotal,
|
TotalAdicionaisMensal = totals.VivoAdicionaisTotal,
|
||||||
TotalGeralMensal = totalGeralMensal,
|
TotalGeralMensal = totalGeralMensal,
|
||||||
|
|
@ -1110,6 +1112,7 @@ namespace line_gestao_api.Services
|
||||||
public int TotalBloqueados { get; set; }
|
public int TotalBloqueados { get; set; }
|
||||||
public int VivoLinhas { get; set; }
|
public int VivoLinhas { get; set; }
|
||||||
public decimal VivoFranquiaTotalGb { get; set; }
|
public decimal VivoFranquiaTotalGb { get; set; }
|
||||||
|
public decimal TotalFranquiaLine { get; set; }
|
||||||
public decimal VivoBaseTotal { get; set; }
|
public decimal VivoBaseTotal { get; set; }
|
||||||
public decimal VivoAdicionaisTotal { get; set; }
|
public decimal VivoAdicionaisTotal { get; set; }
|
||||||
public decimal VivoMinBase { get; set; }
|
public decimal VivoMinBase { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,260 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue