Compare commits
5 Commits
918232ece7
...
20dcaad10c
| Author | SHA1 | Date |
|---|---|---|
|
|
20dcaad10c | |
|
|
5c61fee989 | |
|
|
9b4271d2a5 | |
|
|
382aece077 | |
|
|
c174033583 |
|
|
@ -400,6 +400,7 @@ namespace line_gestao_api.Controllers
|
||||||
Skeelo = req.Skeelo,
|
Skeelo = req.Skeelo,
|
||||||
VivoNewsPlus = req.VivoNewsPlus,
|
VivoNewsPlus = req.VivoNewsPlus,
|
||||||
VivoTravelMundo = req.VivoTravelMundo,
|
VivoTravelMundo = req.VivoTravelMundo,
|
||||||
|
VivoSync = req.VivoSync,
|
||||||
VivoGestaoDispositivo = req.VivoGestaoDispositivo,
|
VivoGestaoDispositivo = req.VivoGestaoDispositivo,
|
||||||
ValorContratoVivo = req.ValorContratoVivo,
|
ValorContratoVivo = req.ValorContratoVivo,
|
||||||
FranquiaLine = req.FranquiaLine,
|
FranquiaLine = req.FranquiaLine,
|
||||||
|
|
@ -408,6 +409,7 @@ namespace line_gestao_api.Controllers
|
||||||
ValorContratoLine = req.ValorContratoLine,
|
ValorContratoLine = req.ValorContratoLine,
|
||||||
Desconto = req.Desconto,
|
Desconto = req.Desconto,
|
||||||
Lucro = req.Lucro,
|
Lucro = req.Lucro,
|
||||||
|
TipoDeChip = req.TipoDeChip?.Trim(),
|
||||||
|
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
UpdatedAt = now
|
UpdatedAt = now
|
||||||
|
|
@ -460,6 +462,7 @@ namespace line_gestao_api.Controllers
|
||||||
x.Skeelo = req.Skeelo;
|
x.Skeelo = req.Skeelo;
|
||||||
x.VivoNewsPlus = req.VivoNewsPlus;
|
x.VivoNewsPlus = req.VivoNewsPlus;
|
||||||
x.VivoTravelMundo = req.VivoTravelMundo;
|
x.VivoTravelMundo = req.VivoTravelMundo;
|
||||||
|
x.VivoSync = req.VivoSync;
|
||||||
x.VivoGestaoDispositivo = req.VivoGestaoDispositivo;
|
x.VivoGestaoDispositivo = req.VivoGestaoDispositivo;
|
||||||
x.ValorContratoVivo = req.ValorContratoVivo;
|
x.ValorContratoVivo = req.ValorContratoVivo;
|
||||||
x.FranquiaLine = req.FranquiaLine;
|
x.FranquiaLine = req.FranquiaLine;
|
||||||
|
|
@ -477,6 +480,7 @@ namespace line_gestao_api.Controllers
|
||||||
x.DataEntregaOpera = ToUtc(req.DataEntregaOpera);
|
x.DataEntregaOpera = ToUtc(req.DataEntregaOpera);
|
||||||
x.DataEntregaCliente = ToUtc(req.DataEntregaCliente);
|
x.DataEntregaCliente = ToUtc(req.DataEntregaCliente);
|
||||||
x.VencConta = req.VencConta?.Trim();
|
x.VencConta = req.VencConta?.Trim();
|
||||||
|
x.TipoDeChip = req.TipoDeChip?.Trim();
|
||||||
|
|
||||||
ApplyReservaRule(x);
|
ApplyReservaRule(x);
|
||||||
x.UpdatedAt = DateTime.UtcNow;
|
x.UpdatedAt = DateTime.UtcNow;
|
||||||
|
|
@ -576,6 +580,7 @@ namespace line_gestao_api.Controllers
|
||||||
Skeelo = TryDecimal(GetCellByHeaderAny(ws, r, map, "SKEELO")),
|
Skeelo = TryDecimal(GetCellByHeaderAny(ws, r, map, "SKEELO")),
|
||||||
VivoNewsPlus = TryDecimal(GetCellByHeaderAny(ws, r, map, "VIVO NEWS PLUS")),
|
VivoNewsPlus = TryDecimal(GetCellByHeaderAny(ws, r, map, "VIVO NEWS PLUS")),
|
||||||
VivoTravelMundo = TryDecimal(GetCellByHeaderAny(ws, r, map, "VIVO TRAVEL MUNDO")),
|
VivoTravelMundo = TryDecimal(GetCellByHeaderAny(ws, r, map, "VIVO TRAVEL MUNDO")),
|
||||||
|
VivoSync = TryDecimal(GetCellByHeaderAny(ws, r, map, "VIVO SYNC")),
|
||||||
VivoGestaoDispositivo = TryDecimal(GetCellByHeaderAny(ws, r, map, "VIVO GESTAO DISPOSITIVO")),
|
VivoGestaoDispositivo = TryDecimal(GetCellByHeaderAny(ws, r, map, "VIVO GESTAO DISPOSITIVO")),
|
||||||
ValorContratoVivo = TryDecimal(GetCellByHeaderAny(ws, r, map, "VALOR CONTRATO VIVO", "VALOR DO CONTRATO VIVO")),
|
ValorContratoVivo = TryDecimal(GetCellByHeaderAny(ws, r, map, "VALOR CONTRATO VIVO", "VALOR DO CONTRATO VIVO")),
|
||||||
FranquiaLine = TryDecimal(GetCellByHeaderAny(ws, r, map, "FRANQUIA LINE", "FRAQUIA LINE")),
|
FranquiaLine = TryDecimal(GetCellByHeaderAny(ws, r, map, "FRANQUIA LINE", "FRAQUIA LINE")),
|
||||||
|
|
@ -593,6 +598,7 @@ namespace line_gestao_api.Controllers
|
||||||
DataEntregaOpera = TryDate(ws, r, map, "DATA DA ENTREGA OPERA."),
|
DataEntregaOpera = TryDate(ws, r, map, "DATA DA ENTREGA OPERA."),
|
||||||
DataEntregaCliente = TryDate(ws, r, map, "DATA DA ENTREGA CLIENTE"),
|
DataEntregaCliente = TryDate(ws, r, map, "DATA DA ENTREGA CLIENTE"),
|
||||||
VencConta = GetCellByHeader(ws, r, map, "VENC. DA CONTA"),
|
VencConta = GetCellByHeader(ws, r, map, "VENC. DA CONTA"),
|
||||||
|
TipoDeChip = GetCellByHeaderAny(ws, r, map, "TIPO DE CHIP", "TIPO CHIP"),
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
UpdatedAt = now
|
UpdatedAt = now
|
||||||
};
|
};
|
||||||
|
|
@ -1520,9 +1526,9 @@ namespace line_gestao_api.Controllers
|
||||||
|
|
||||||
private async Task ImportResumoTabela1(IXLWorksheet ws, DateTime now)
|
private async Task ImportResumoTabela1(IXLWorksheet ws, DateTime now)
|
||||||
{
|
{
|
||||||
const int headerRow = 5;
|
var lastRowUsed = ws.LastRowUsed()?.RowNumber() ?? 1;
|
||||||
const int totalRow = 72;
|
var headerRow = FindHeaderRowForMacrophonyPlans(ws, 1, lastRowUsed);
|
||||||
var lastRow = Math.Min(totalRow - 1, ws.LastRowUsed()?.RowNumber() ?? totalRow - 1);
|
if (headerRow == 0) return;
|
||||||
|
|
||||||
var map = BuildHeaderMap(ws.Row(headerRow));
|
var map = BuildHeaderMap(ws.Row(headerRow));
|
||||||
var colPlano = GetCol(map, "PLANO CONTRATO");
|
var colPlano = GetCol(map, "PLANO CONTRATO");
|
||||||
|
|
@ -1533,8 +1539,15 @@ namespace line_gestao_api.Controllers
|
||||||
var colValorTotal = GetCol(map, "VALOR TOTAL");
|
var colValorTotal = GetCol(map, "VALOR TOTAL");
|
||||||
|
|
||||||
var buffer = new List<ResumoMacrophonyPlan>(200);
|
var buffer = new List<ResumoMacrophonyPlan>(200);
|
||||||
|
string? lastPlanoContrato = null;
|
||||||
|
decimal? lastGb = null;
|
||||||
|
var dataStarted = false;
|
||||||
|
var emptyDataStreak = 0;
|
||||||
|
int? totalRowIndex = null;
|
||||||
|
var missingPlanoCount = 0;
|
||||||
|
var missingGbCount = 0;
|
||||||
|
|
||||||
for (int r = headerRow + 1; r <= lastRow; r++)
|
for (int r = headerRow + 1; r <= lastRowUsed; r++)
|
||||||
{
|
{
|
||||||
var plano = GetCellString(ws, r, colPlano);
|
var plano = GetCellString(ws, r, colPlano);
|
||||||
var gb = GetCellString(ws, r, colGb);
|
var gb = GetCellString(ws, r, colGb);
|
||||||
|
|
@ -1543,27 +1556,90 @@ namespace line_gestao_api.Controllers
|
||||||
var totalLinhas = GetCellString(ws, r, colTotalLinhas);
|
var totalLinhas = GetCellString(ws, r, colTotalLinhas);
|
||||||
var valorTotal = GetCellString(ws, r, colValorTotal);
|
var valorTotal = GetCellString(ws, r, colValorTotal);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(plano)
|
var isPlanoTotal = !string.IsNullOrWhiteSpace(plano)
|
||||||
|
&& NormalizeHeader(plano) == NormalizeHeader("TOTAL");
|
||||||
|
|
||||||
|
if (isPlanoTotal)
|
||||||
|
{
|
||||||
|
totalRowIndex = r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasAnyValue = !(string.IsNullOrWhiteSpace(plano)
|
||||||
&& string.IsNullOrWhiteSpace(gb)
|
&& string.IsNullOrWhiteSpace(gb)
|
||||||
&& string.IsNullOrWhiteSpace(valorInd)
|
&& string.IsNullOrWhiteSpace(valorInd)
|
||||||
&& string.IsNullOrWhiteSpace(franquia)
|
&& string.IsNullOrWhiteSpace(franquia)
|
||||||
&& string.IsNullOrWhiteSpace(totalLinhas)
|
&& string.IsNullOrWhiteSpace(totalLinhas)
|
||||||
&& string.IsNullOrWhiteSpace(valorTotal))
|
&& string.IsNullOrWhiteSpace(valorTotal));
|
||||||
|
|
||||||
|
if (!hasAnyValue)
|
||||||
|
{
|
||||||
|
if (dataStarted)
|
||||||
|
{
|
||||||
|
emptyDataStreak++;
|
||||||
|
if (emptyDataStreak >= 2) break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyDataStreak = 0;
|
||||||
|
|
||||||
|
var franquiaValue = TryDecimal(franquia);
|
||||||
|
var totalLinhasValue = TryNullableInt(totalLinhas);
|
||||||
|
var isDataRow = franquiaValue.HasValue || totalLinhasValue.HasValue;
|
||||||
|
if (isDataRow) dataStarted = true;
|
||||||
|
if (!isDataRow && dataStarted)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isDataRow)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var planoNormalized = NormalizeHeader(plano);
|
||||||
|
if (!string.IsNullOrWhiteSpace(plano)
|
||||||
|
&& planoNormalized != NormalizeHeader("PLANO CONTRATO")
|
||||||
|
&& planoNormalized != NormalizeHeader("TOTAL"))
|
||||||
|
{
|
||||||
|
lastPlanoContrato = plano.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
var gbValue = TryDecimal(gb);
|
||||||
|
if (gbValue.HasValue)
|
||||||
|
{
|
||||||
|
lastGb = gbValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var resolvedPlano = isDataRow
|
||||||
|
? (string.IsNullOrWhiteSpace(plano) ? lastPlanoContrato : plano.Trim())
|
||||||
|
: (string.IsNullOrWhiteSpace(plano) ? null : plano.Trim());
|
||||||
|
|
||||||
|
var resolvedGb = isDataRow
|
||||||
|
? (gbValue ?? lastGb)
|
||||||
|
: gbValue;
|
||||||
|
|
||||||
|
if (isDataRow && string.IsNullOrWhiteSpace(resolvedPlano))
|
||||||
|
{
|
||||||
|
missingPlanoCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDataRow && !resolvedGb.HasValue)
|
||||||
|
{
|
||||||
|
missingGbCount++;
|
||||||
|
}
|
||||||
|
|
||||||
var vivoTravelCell = ws.Cell(r, 8).GetString();
|
var vivoTravelCell = ws.Cell(r, 8).GetString();
|
||||||
var vivoTravel = !string.IsNullOrWhiteSpace(vivoTravelCell)
|
var vivoTravel = !string.IsNullOrWhiteSpace(vivoTravelCell)
|
||||||
&& vivoTravelCell.Contains("VIVO TRAVEL", StringComparison.OrdinalIgnoreCase);
|
&& vivoTravelCell.Contains("VIVO TRAVEL", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
buffer.Add(new ResumoMacrophonyPlan
|
buffer.Add(new ResumoMacrophonyPlan
|
||||||
{
|
{
|
||||||
PlanoContrato = string.IsNullOrWhiteSpace(plano) ? null : plano.Trim(),
|
PlanoContrato = string.IsNullOrWhiteSpace(resolvedPlano) ? null : resolvedPlano,
|
||||||
Gb = TryDecimal(gb),
|
Gb = resolvedGb,
|
||||||
ValorIndividualComSvas = TryDecimal(valorInd),
|
ValorIndividualComSvas = TryDecimal(valorInd),
|
||||||
FranquiaGb = TryDecimal(franquia),
|
FranquiaGb = franquiaValue,
|
||||||
TotalLinhas = TryNullableInt(totalLinhas),
|
TotalLinhas = totalLinhasValue,
|
||||||
ValorTotal = TryDecimal(valorTotal),
|
ValorTotal = TryDecimal(valorTotal),
|
||||||
VivoTravel = vivoTravel,
|
VivoTravel = vivoTravel,
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
|
|
@ -1577,11 +1653,21 @@ namespace line_gestao_api.Controllers
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (missingPlanoCount > 0 || missingGbCount > 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Import RESUMO/MACROPHONY: {missingPlanoCount} linhas sem PLANO CONTRATO e {missingGbCount} linhas sem GB.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalRowIndex == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var total = new ResumoMacrophonyTotal
|
var total = new ResumoMacrophonyTotal
|
||||||
{
|
{
|
||||||
FranquiaGbTotal = TryDecimal(GetCellString(ws, totalRow, colFranquiaGb)),
|
FranquiaGbTotal = TryDecimal(GetCellString(ws, totalRowIndex.Value, colFranquiaGb)),
|
||||||
TotalLinhasTotal = TryNullableInt(GetCellString(ws, totalRow, colTotalLinhas)),
|
TotalLinhasTotal = TryNullableInt(GetCellString(ws, totalRowIndex.Value, colTotalLinhas)),
|
||||||
ValorTotal = TryDecimal(GetCellString(ws, totalRow, colValorTotal)),
|
ValorTotal = TryDecimal(GetCellString(ws, totalRowIndex.Value, colValorTotal)),
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
UpdatedAt = now
|
UpdatedAt = now
|
||||||
};
|
};
|
||||||
|
|
@ -1590,6 +1676,27 @@ namespace line_gestao_api.Controllers
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int FindHeaderRowForMacrophonyPlans(IXLWorksheet ws, int startRow, int lastRow)
|
||||||
|
{
|
||||||
|
for (int r = startRow; r <= lastRow; r++)
|
||||||
|
{
|
||||||
|
var row = ws.Row(r);
|
||||||
|
if (!row.CellsUsed().Any()) continue;
|
||||||
|
|
||||||
|
var map = BuildHeaderMap(row);
|
||||||
|
var hasPlano = GetCol(map, "PLANO CONTRATO") > 0;
|
||||||
|
var hasGb = GetCol(map, "GB") > 0;
|
||||||
|
var hasTotalLinhas = GetColAny(map, "TOTAL DE LINHAS", "TOTAL LINHAS") > 0;
|
||||||
|
|
||||||
|
if (hasPlano && hasGb && hasTotalLinhas)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ImportResumoTabela2(IXLWorksheet ws, DateTime now)
|
private async Task ImportResumoTabela2(IXLWorksheet ws, DateTime now)
|
||||||
{
|
{
|
||||||
const int headerRow = 5;
|
const int headerRow = 5;
|
||||||
|
|
@ -1714,9 +1821,9 @@ namespace line_gestao_api.Controllers
|
||||||
|
|
||||||
private async Task ImportResumoTabela4(IXLWorksheet ws, DateTime now)
|
private async Task ImportResumoTabela4(IXLWorksheet ws, DateTime now)
|
||||||
{
|
{
|
||||||
const int headerRow = 74;
|
var lastRowUsed = ws.LastRowUsed()?.RowNumber() ?? 1;
|
||||||
const int totalRow = 81;
|
var headerRow = FindHeaderRowForPlanoContratoResumo(ws, 1, lastRowUsed);
|
||||||
var lastRow = Math.Min(totalRow - 1, ws.LastRowUsed()?.RowNumber() ?? totalRow - 1);
|
if (headerRow == 0) return;
|
||||||
|
|
||||||
var map = BuildHeaderMap(ws.Row(headerRow));
|
var map = BuildHeaderMap(ws.Row(headerRow));
|
||||||
var colPlano = GetCol(map, "PLANO CONTRATO");
|
var colPlano = GetCol(map, "PLANO CONTRATO");
|
||||||
|
|
@ -1725,10 +1832,17 @@ namespace line_gestao_api.Controllers
|
||||||
var colFranquiaGb = GetColAny(map, "FRANQUIA GB", "FRAQUIA GB");
|
var colFranquiaGb = GetColAny(map, "FRANQUIA GB", "FRAQUIA GB");
|
||||||
var colTotalLinhas = GetColAny(map, "TOTAL DE LINHAS", "TOTAL LINHAS");
|
var colTotalLinhas = GetColAny(map, "TOTAL DE LINHAS", "TOTAL LINHAS");
|
||||||
var colValorTotal = GetCol(map, "VALOR TOTAL");
|
var colValorTotal = GetCol(map, "VALOR TOTAL");
|
||||||
|
var colCliente = GetCol(map, "CLIENTE");
|
||||||
|
var colQtdLinhas = GetColAny(map, "QTD DE LINHAS", "QTD. DE LINHAS", "QTD LINHAS");
|
||||||
|
|
||||||
var buffer = new List<ResumoPlanoContratoResumo>(200);
|
var buffer = new List<ResumoPlanoContratoResumo>(200);
|
||||||
|
string? lastPlanoContrato = null;
|
||||||
|
var dataStarted = false;
|
||||||
|
var emptyDataStreak = 0;
|
||||||
|
int? totalRowIndex = null;
|
||||||
|
var missingPlanoCount = 0;
|
||||||
|
|
||||||
for (int r = headerRow + 1; r <= lastRow; r++)
|
for (int r = headerRow + 1; r <= lastRowUsed; r++)
|
||||||
{
|
{
|
||||||
var plano = GetCellString(ws, r, colPlano);
|
var plano = GetCellString(ws, r, colPlano);
|
||||||
var gb = GetCellString(ws, r, colGb);
|
var gb = GetCellString(ws, r, colGb);
|
||||||
|
|
@ -1736,20 +1850,68 @@ namespace line_gestao_api.Controllers
|
||||||
var franquia = GetCellString(ws, r, colFranquiaGb);
|
var franquia = GetCellString(ws, r, colFranquiaGb);
|
||||||
var totalLinhas = GetCellString(ws, r, colTotalLinhas);
|
var totalLinhas = GetCellString(ws, r, colTotalLinhas);
|
||||||
var valorTotal = GetCellString(ws, r, colValorTotal);
|
var valorTotal = GetCellString(ws, r, colValorTotal);
|
||||||
|
var cliente = GetCellString(ws, r, colCliente);
|
||||||
|
var qtdLinhas = GetCellString(ws, r, colQtdLinhas);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(plano)
|
var isPlanoTotal = !string.IsNullOrWhiteSpace(plano)
|
||||||
|
&& NormalizeHeader(plano) == NormalizeHeader("TOTAL");
|
||||||
|
|
||||||
|
if (isPlanoTotal)
|
||||||
|
{
|
||||||
|
totalRowIndex = r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasAnyValue = !(string.IsNullOrWhiteSpace(plano)
|
||||||
&& string.IsNullOrWhiteSpace(gb)
|
&& string.IsNullOrWhiteSpace(gb)
|
||||||
&& string.IsNullOrWhiteSpace(valorInd)
|
&& string.IsNullOrWhiteSpace(valorInd)
|
||||||
&& string.IsNullOrWhiteSpace(franquia)
|
&& string.IsNullOrWhiteSpace(franquia)
|
||||||
&& string.IsNullOrWhiteSpace(totalLinhas)
|
&& string.IsNullOrWhiteSpace(totalLinhas)
|
||||||
&& string.IsNullOrWhiteSpace(valorTotal))
|
&& string.IsNullOrWhiteSpace(valorTotal)
|
||||||
|
&& string.IsNullOrWhiteSpace(cliente)
|
||||||
|
&& string.IsNullOrWhiteSpace(qtdLinhas));
|
||||||
|
|
||||||
|
if (!hasAnyValue)
|
||||||
{
|
{
|
||||||
|
if (dataStarted)
|
||||||
|
{
|
||||||
|
emptyDataStreak++;
|
||||||
|
if (emptyDataStreak >= 2) break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emptyDataStreak = 0;
|
||||||
|
|
||||||
|
var isDataRow = !string.IsNullOrWhiteSpace(cliente) || TryNullableInt(qtdLinhas).HasValue;
|
||||||
|
|
||||||
|
var planoNormalized = NormalizeHeader(plano);
|
||||||
|
if (!string.IsNullOrWhiteSpace(plano)
|
||||||
|
&& planoNormalized != NormalizeHeader("PLANO CONTRATO")
|
||||||
|
&& planoNormalized != NormalizeHeader("TOTAL"))
|
||||||
|
{
|
||||||
|
lastPlanoContrato = plano.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDataRow && dataStarted)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDataRow) dataStarted = true;
|
||||||
|
|
||||||
|
var resolvedPlano = isDataRow
|
||||||
|
? (string.IsNullOrWhiteSpace(plano) ? lastPlanoContrato : plano.Trim())
|
||||||
|
: (string.IsNullOrWhiteSpace(plano) ? null : plano.Trim());
|
||||||
|
|
||||||
|
if (isDataRow && string.IsNullOrWhiteSpace(resolvedPlano))
|
||||||
|
{
|
||||||
|
missingPlanoCount++;
|
||||||
|
}
|
||||||
|
|
||||||
buffer.Add(new ResumoPlanoContratoResumo
|
buffer.Add(new ResumoPlanoContratoResumo
|
||||||
{
|
{
|
||||||
PlanoContrato = string.IsNullOrWhiteSpace(plano) ? null : plano.Trim(),
|
PlanoContrato = string.IsNullOrWhiteSpace(resolvedPlano) ? null : resolvedPlano,
|
||||||
Gb = TryDecimal(gb),
|
Gb = TryDecimal(gb),
|
||||||
ValorIndividualComSvas = TryDecimal(valorInd),
|
ValorIndividualComSvas = TryDecimal(valorInd),
|
||||||
FranquiaGb = TryDecimal(franquia),
|
FranquiaGb = TryDecimal(franquia),
|
||||||
|
|
@ -1766,9 +1928,19 @@ namespace line_gestao_api.Controllers
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (missingPlanoCount > 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Import RESUMO/PLANO CONTRATO: {missingPlanoCount} linhas de dados ficaram sem PLANO CONTRATO.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalRowIndex == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var total = new ResumoPlanoContratoTotal
|
var total = new ResumoPlanoContratoTotal
|
||||||
{
|
{
|
||||||
ValorTotal = TryDecimal(ws.Cell(totalRow, 7).GetString()),
|
ValorTotal = TryDecimal(GetCellString(ws, totalRowIndex.Value, colValorTotal)),
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
UpdatedAt = now
|
UpdatedAt = now
|
||||||
};
|
};
|
||||||
|
|
@ -1777,6 +1949,27 @@ namespace line_gestao_api.Controllers
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int FindHeaderRowForPlanoContratoResumo(IXLWorksheet ws, int startRow, int lastRow)
|
||||||
|
{
|
||||||
|
for (int r = startRow; r <= lastRow; r++)
|
||||||
|
{
|
||||||
|
var row = ws.Row(r);
|
||||||
|
if (!row.CellsUsed().Any()) continue;
|
||||||
|
|
||||||
|
var map = BuildHeaderMap(row);
|
||||||
|
var hasPlano = GetCol(map, "PLANO CONTRATO") > 0;
|
||||||
|
var hasCliente = GetCol(map, "CLIENTE") > 0;
|
||||||
|
var hasQtd = GetColAny(map, "QTD DE LINHAS", "QTD. DE LINHAS", "QTD LINHAS") > 0;
|
||||||
|
|
||||||
|
if (hasPlano && hasCliente && hasQtd)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ImportResumoTabela5(IXLWorksheet ws, DateTime now)
|
private async Task ImportResumoTabela5(IXLWorksheet ws, DateTime now)
|
||||||
{
|
{
|
||||||
const int headerRow = 83;
|
const int headerRow = 83;
|
||||||
|
|
@ -1814,34 +2007,78 @@ namespace line_gestao_api.Controllers
|
||||||
|
|
||||||
private async Task ImportResumoTabela6(IXLWorksheet ws, DateTime now)
|
private async Task ImportResumoTabela6(IXLWorksheet ws, DateTime now)
|
||||||
{
|
{
|
||||||
const int headerRow = 91;
|
var lastRowUsed = ws.LastRowUsed()?.RowNumber() ?? 1;
|
||||||
const int totalRow = 139;
|
var sectionRow = FindSectionRow(ws, "LINHAS NA RESERVA");
|
||||||
var lastRow = Math.Min(totalRow - 1, ws.LastRowUsed()?.RowNumber() ?? totalRow - 1);
|
if (sectionRow == 0) return;
|
||||||
|
|
||||||
|
var headerRow = FindHeaderRowForReserva(ws, sectionRow + 1, lastRowUsed);
|
||||||
|
if (headerRow == 0) return;
|
||||||
|
|
||||||
var map = BuildHeaderMap(ws.Row(headerRow));
|
var map = BuildHeaderMap(ws.Row(headerRow));
|
||||||
var colDdd = GetCol(map, "DDD");
|
var colDdd = GetCol(map, "DDD");
|
||||||
var colFranquiaGb = GetColAny(map, "FRANQUIA GB", "FRAQUIA GB");
|
var colFranquiaGb = GetColAny(map, "FRANQUIA GB", "FRAQUIA GB");
|
||||||
var colQtdLinhas = GetColAny(map, "QTD. DE LINHAS", "QTD DE LINHAS", "QTD. LINHAS");
|
var colQtdLinhas = GetColAny(map, "QTD. DE LINHAS", "QTD DE LINHAS", "QTD. LINHAS", "QTDLINHAS");
|
||||||
var colTotal = GetCol(map, "TOTAL");
|
var colTotal = GetCol(map, "TOTAL");
|
||||||
|
|
||||||
var buffer = new List<ResumoReservaLine>(200);
|
var buffer = new List<ResumoReservaLine>(200);
|
||||||
decimal? lastTotal = null;
|
decimal? lastTotal = null;
|
||||||
|
string? lastDddValid = null;
|
||||||
|
var dataStarted = false;
|
||||||
|
var emptyRowStreak = 0;
|
||||||
|
int? totalRowIndex = null;
|
||||||
|
|
||||||
for (int r = headerRow + 1; r <= lastRow; r++)
|
for (int r = headerRow + 1; r <= lastRowUsed; r++)
|
||||||
{
|
{
|
||||||
var ddd = GetCellString(ws, r, colDdd);
|
var ddd = GetCellString(ws, r, colDdd);
|
||||||
var franquia = GetCellString(ws, r, colFranquiaGb);
|
var franquia = GetCellString(ws, r, colFranquiaGb);
|
||||||
var qtdLinhas = GetCellString(ws, r, colQtdLinhas);
|
var qtdLinhas = GetCellString(ws, r, colQtdLinhas);
|
||||||
var total = GetCellString(ws, r, colTotal);
|
var total = GetCellString(ws, r, colTotal);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(ddd)
|
var hasAnyValue = !(string.IsNullOrWhiteSpace(ddd)
|
||||||
&& string.IsNullOrWhiteSpace(franquia)
|
&& string.IsNullOrWhiteSpace(franquia)
|
||||||
&& string.IsNullOrWhiteSpace(qtdLinhas)
|
&& string.IsNullOrWhiteSpace(qtdLinhas)
|
||||||
&& string.IsNullOrWhiteSpace(total))
|
&& string.IsNullOrWhiteSpace(total));
|
||||||
|
|
||||||
|
if (!hasAnyValue)
|
||||||
{
|
{
|
||||||
|
if (dataStarted)
|
||||||
|
{
|
||||||
|
emptyRowStreak++;
|
||||||
|
if (emptyRowStreak >= 2) break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emptyRowStreak = 0;
|
||||||
|
|
||||||
|
var franquiaValue = TryDecimal(franquia);
|
||||||
|
var qtdValue = TryNullableInt(qtdLinhas);
|
||||||
|
var isDataRow = franquiaValue.HasValue || qtdValue.HasValue;
|
||||||
|
var dddCandidate = NullIfEmptyDigits(ddd);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(dddCandidate))
|
||||||
|
{
|
||||||
|
lastDddValid = dddCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isTotalRow = !isDataRow && !string.IsNullOrWhiteSpace(total);
|
||||||
|
if (isTotalRow)
|
||||||
|
{
|
||||||
|
totalRowIndex = r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDataRow && dataStarted)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDataRow) dataStarted = true;
|
||||||
|
|
||||||
|
var resolvedDdd = isDataRow
|
||||||
|
? (dddCandidate ?? lastDddValid)
|
||||||
|
: dddCandidate;
|
||||||
|
|
||||||
var totalValue = TryDecimal(total);
|
var totalValue = TryDecimal(total);
|
||||||
if (!totalValue.HasValue && lastTotal.HasValue)
|
if (!totalValue.HasValue && lastTotal.HasValue)
|
||||||
{
|
{
|
||||||
|
|
@ -1854,25 +2091,36 @@ namespace line_gestao_api.Controllers
|
||||||
|
|
||||||
buffer.Add(new ResumoReservaLine
|
buffer.Add(new ResumoReservaLine
|
||||||
{
|
{
|
||||||
Ddd = string.IsNullOrWhiteSpace(ddd) ? null : ddd.Trim(),
|
Ddd = string.IsNullOrWhiteSpace(resolvedDdd) ? null : resolvedDdd,
|
||||||
FranquiaGb = TryDecimal(franquia),
|
FranquiaGb = franquiaValue,
|
||||||
QtdLinhas = TryNullableInt(qtdLinhas),
|
QtdLinhas = qtdValue,
|
||||||
Total = totalValue,
|
Total = totalValue,
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
UpdatedAt = now
|
UpdatedAt = now
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var missingDddCount = buffer.Count(x => x.Ddd == null && (x.FranquiaGb.HasValue || x.QtdLinhas.HasValue));
|
||||||
|
if (missingDddCount > 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Import RESUMO/RESERVA: {missingDddCount} linhas de dados ficaram sem DDD.");
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer.Count > 0)
|
if (buffer.Count > 0)
|
||||||
{
|
{
|
||||||
await _db.ResumoReservaLines.AddRangeAsync(buffer);
|
await _db.ResumoReservaLines.AddRangeAsync(buffer);
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (totalRowIndex == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var totalEntity = new ResumoReservaTotal
|
var totalEntity = new ResumoReservaTotal
|
||||||
{
|
{
|
||||||
QtdLinhasTotal = TryNullableInt(GetCellString(ws, totalRow, colQtdLinhas)),
|
QtdLinhasTotal = TryNullableInt(GetCellString(ws, totalRowIndex.Value, colQtdLinhas)),
|
||||||
Total = TryDecimal(GetCellString(ws, totalRow, colTotal)),
|
Total = TryDecimal(GetCellString(ws, totalRowIndex.Value, colTotal)),
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
UpdatedAt = now
|
UpdatedAt = now
|
||||||
};
|
};
|
||||||
|
|
@ -1881,6 +2129,43 @@ namespace line_gestao_api.Controllers
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int FindSectionRow(IXLWorksheet ws, string sectionName)
|
||||||
|
{
|
||||||
|
var normalizedTarget = NormalizeHeader(sectionName);
|
||||||
|
foreach (var row in ws.RowsUsed())
|
||||||
|
{
|
||||||
|
foreach (var cell in row.CellsUsed())
|
||||||
|
{
|
||||||
|
var key = NormalizeHeader(cell.GetString());
|
||||||
|
if (string.IsNullOrWhiteSpace(key)) continue;
|
||||||
|
if (key.Contains(normalizedTarget)) return row.RowNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FindHeaderRowForReserva(IXLWorksheet ws, int startRow, int lastRow)
|
||||||
|
{
|
||||||
|
for (int r = startRow; r <= lastRow; r++)
|
||||||
|
{
|
||||||
|
var row = ws.Row(r);
|
||||||
|
if (!row.CellsUsed().Any()) continue;
|
||||||
|
|
||||||
|
var map = BuildHeaderMap(row);
|
||||||
|
var hasDdd = GetCol(map, "DDD") > 0;
|
||||||
|
var hasFranquia = GetColAny(map, "FRANQUIA GB", "FRAQUIA GB") > 0;
|
||||||
|
var hasQtd = GetColAny(map, "QTD. DE LINHAS", "QTD DE LINHAS", "QTD. LINHAS", "QTDLINHAS") > 0;
|
||||||
|
|
||||||
|
if (hasDdd && hasFranquia && hasQtd)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ImportControleRecebidosSheet(IXLWorksheet ws, int year)
|
private async Task ImportControleRecebidosSheet(IXLWorksheet ws, int year)
|
||||||
{
|
{
|
||||||
var buffer = new List<ControleRecebidoLine>(500);
|
var buffer = new List<ControleRecebidoLine>(500);
|
||||||
|
|
@ -2159,6 +2444,7 @@ namespace line_gestao_api.Controllers
|
||||||
Skeelo = x.Skeelo,
|
Skeelo = x.Skeelo,
|
||||||
VivoNewsPlus = x.VivoNewsPlus,
|
VivoNewsPlus = x.VivoNewsPlus,
|
||||||
VivoTravelMundo = x.VivoTravelMundo,
|
VivoTravelMundo = x.VivoTravelMundo,
|
||||||
|
VivoSync = x.VivoSync,
|
||||||
VivoGestaoDispositivo = x.VivoGestaoDispositivo,
|
VivoGestaoDispositivo = x.VivoGestaoDispositivo,
|
||||||
ValorContratoVivo = x.ValorContratoVivo,
|
ValorContratoVivo = x.ValorContratoVivo,
|
||||||
FranquiaLine = x.FranquiaLine,
|
FranquiaLine = x.FranquiaLine,
|
||||||
|
|
@ -2175,7 +2461,8 @@ namespace line_gestao_api.Controllers
|
||||||
Solicitante = x.Solicitante,
|
Solicitante = x.Solicitante,
|
||||||
DataEntregaOpera = x.DataEntregaOpera,
|
DataEntregaOpera = x.DataEntregaOpera,
|
||||||
DataEntregaCliente = x.DataEntregaCliente,
|
DataEntregaCliente = x.DataEntregaCliente,
|
||||||
VencConta = x.VencConta
|
VencConta = x.VencConta,
|
||||||
|
TipoDeChip = x.TipoDeChip
|
||||||
};
|
};
|
||||||
|
|
||||||
private static void ApplyReservaRule(MobileLine x)
|
private static void ApplyReservaRule(MobileLine x)
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ namespace line_gestao_api.Dtos
|
||||||
public decimal? Skeelo { get; set; }
|
public decimal? Skeelo { get; set; }
|
||||||
public decimal? VivoNewsPlus { get; set; }
|
public decimal? VivoNewsPlus { get; set; }
|
||||||
public decimal? VivoTravelMundo { get; set; }
|
public decimal? VivoTravelMundo { get; set; }
|
||||||
|
public decimal? VivoSync { get; set; }
|
||||||
public decimal? VivoGestaoDispositivo { get; set; }
|
public decimal? VivoGestaoDispositivo { get; set; }
|
||||||
public decimal? ValorContratoVivo { get; set; }
|
public decimal? ValorContratoVivo { get; set; }
|
||||||
|
|
||||||
|
|
@ -65,5 +66,10 @@ namespace line_gestao_api.Dtos
|
||||||
// ==========================
|
// ==========================
|
||||||
public decimal? Desconto { get; set; }
|
public decimal? Desconto { get; set; }
|
||||||
public decimal? Lucro { get; set; }
|
public decimal? Lucro { get; set; }
|
||||||
|
|
||||||
|
// ==========================
|
||||||
|
// Identificação adicional
|
||||||
|
// ==========================
|
||||||
|
public string? TipoDeChip { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
public decimal? Skeelo { get; set; }
|
public decimal? Skeelo { get; set; }
|
||||||
public decimal? VivoNewsPlus { get; set; }
|
public decimal? VivoNewsPlus { get; set; }
|
||||||
public decimal? VivoTravelMundo { get; set; }
|
public decimal? VivoTravelMundo { get; set; }
|
||||||
|
public decimal? VivoSync { get; set; }
|
||||||
public decimal? VivoGestaoDispositivo { get; set; }
|
public decimal? VivoGestaoDispositivo { get; set; }
|
||||||
public decimal? ValorContratoVivo { get; set; }
|
public decimal? ValorContratoVivo { get; set; }
|
||||||
|
|
||||||
|
|
@ -53,6 +54,7 @@
|
||||||
public DateTime? DataEntregaOpera { get; set; }
|
public DateTime? DataEntregaOpera { get; set; }
|
||||||
public DateTime? DataEntregaCliente { get; set; }
|
public DateTime? DataEntregaCliente { get; set; }
|
||||||
public string? VencConta { get; set; }
|
public string? VencConta { get; set; }
|
||||||
|
public string? TipoDeChip { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ UPDATE REQUEST (SEM Id)
|
// ✅ UPDATE REQUEST (SEM Id)
|
||||||
|
|
@ -72,6 +74,7 @@
|
||||||
public decimal? Skeelo { get; set; }
|
public decimal? Skeelo { get; set; }
|
||||||
public decimal? VivoNewsPlus { get; set; }
|
public decimal? VivoNewsPlus { get; set; }
|
||||||
public decimal? VivoTravelMundo { get; set; }
|
public decimal? VivoTravelMundo { get; set; }
|
||||||
|
public decimal? VivoSync { get; set; }
|
||||||
public decimal? VivoGestaoDispositivo { get; set; }
|
public decimal? VivoGestaoDispositivo { get; set; }
|
||||||
public decimal? ValorContratoVivo { get; set; }
|
public decimal? ValorContratoVivo { get; set; }
|
||||||
|
|
||||||
|
|
@ -92,6 +95,7 @@
|
||||||
public DateTime? DataEntregaOpera { get; set; }
|
public DateTime? DataEntregaOpera { get; set; }
|
||||||
public DateTime? DataEntregaCliente { get; set; }
|
public DateTime? DataEntregaCliente { get; set; }
|
||||||
public string? VencConta { get; set; }
|
public string? VencConta { get; set; }
|
||||||
|
public string? TipoDeChip { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportResultDto
|
public class ImportResultDto
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ namespace line_gestao_api.Models
|
||||||
public decimal? Skeelo { get; set; }
|
public decimal? Skeelo { get; set; }
|
||||||
public decimal? VivoNewsPlus { get; set; }
|
public decimal? VivoNewsPlus { get; set; }
|
||||||
public decimal? VivoTravelMundo { get; set; }
|
public decimal? VivoTravelMundo { get; set; }
|
||||||
|
public decimal? VivoSync { get; set; }
|
||||||
public decimal? VivoGestaoDispositivo { get; set; }
|
public decimal? VivoGestaoDispositivo { get; set; }
|
||||||
public decimal? ValorContratoVivo { get; set; }
|
public decimal? ValorContratoVivo { get; set; }
|
||||||
|
|
||||||
|
|
@ -59,6 +60,8 @@ namespace line_gestao_api.Models
|
||||||
|
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string? VencConta { get; set; }
|
public string? VencConta { get; set; }
|
||||||
|
[MaxLength(80)]
|
||||||
|
public string? TipoDeChip { get; set; }
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue