|
|
@@ -447,7 +447,7 @@ function parseDataBusca(termo) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
-export async function listarAvaliacoes({ page = 1, pageSize = 20, setor, resolvido, sentimento, statusCancelamento, scoreMax, busca, ordenacao } = {}) {
|
|
|
+export async function listarAvaliacoes({ page = 1, pageSize = 20, setor, resolvido, sentimento, statusCancelamento, scoreMax, busca, ordenacao, dataInicio, dataFim } = {}) {
|
|
|
// ordena por Abertura (data do atendimento, é o que aparece no card) e não por
|
|
|
// UpdatedAt (data da avaliação da IA) — os dois divergem e ordenar pelo errado
|
|
|
// deixa a lista com datas aparentemente fora de ordem
|
|
|
@@ -463,6 +463,8 @@ export async function listarAvaliacoes({ page = 1, pageSize = 20, setor, resolvi
|
|
|
if (statusCancelamento) query.where("StatusCancelamento", statusCancelamento);
|
|
|
if (scoreMax !== undefined) query.where("ScoreAtendente", "<=", scoreMax);
|
|
|
if (setor) query.where("a.Setor", setor);
|
|
|
+ if (dataInicio) query.where("a.Abertura", ">=", dataInicio);
|
|
|
+ if (dataFim) query.where("a.Abertura", "<=", `${dataFim} 23:59:59`);
|
|
|
|
|
|
const termo = typeof busca === "string" ? busca.trim() : "";
|
|
|
|
|
|
@@ -517,8 +519,9 @@ export async function listarSetores() {
|
|
|
return rows.map((r) => ({ sigla: r.Setor, nome: nomeSetor(r.Setor), total: Number(r.total) }));
|
|
|
}
|
|
|
|
|
|
-export async function estatisticasAvaliacoes({ setor, resolvido, sentimento, statusCancelamento, busca } = {}) {
|
|
|
+export async function estatisticasAvaliacoes({ setor, resolvido, sentimento, statusCancelamento, busca, dataInicio, dataFim } = {}) {
|
|
|
const termo = typeof busca === "string" ? busca.trim() : "";
|
|
|
+ const precisaJoin = Boolean(setor || termo || dataInicio || dataFim);
|
|
|
|
|
|
// mesmos filtros de listarAvaliacoes, para os cards do topo baterem com a lista abaixo
|
|
|
// deles na tela (pendentes/totalAtendimentos ficam de fora de propósito: representam o
|
|
|
@@ -526,13 +529,15 @@ export async function estatisticasAvaliacoes({ setor, resolvido, sentimento, sta
|
|
|
// que só existe em quem já foi avaliado)
|
|
|
const base = () => {
|
|
|
const q = AtendimentoAvaliacao.query().where("Avaliavel", true);
|
|
|
- if (setor || termo) {
|
|
|
+ if (precisaJoin) {
|
|
|
q.join("atendimentos as a", "a.Id", "atendimento_avaliacoes.AtendimentoId");
|
|
|
}
|
|
|
if (setor) q.where("a.Setor", setor);
|
|
|
if (resolvido) q.where("Resolvido", resolvido);
|
|
|
if (sentimento) q.where("Sentimento", sentimento);
|
|
|
if (statusCancelamento) q.where("StatusCancelamento", statusCancelamento);
|
|
|
+ if (dataInicio) q.where("a.Abertura", ">=", dataInicio);
|
|
|
+ if (dataFim) q.where("a.Abertura", "<=", `${dataFim} 23:59:59`);
|
|
|
if (termo) {
|
|
|
const like = `%${termo.replace(/[\\%_]/g, (ch) => `\\${ch}`)}%`;
|
|
|
const data = parseDataBusca(termo);
|
|
|
@@ -546,7 +551,7 @@ export async function estatisticasAvaliacoes({ setor, resolvido, sentimento, sta
|
|
|
return q;
|
|
|
};
|
|
|
|
|
|
- const [scoreRow, avaliados, porResolvido, porSentimento, porCancelamento, visitas, pendentes, totalAtendimentos] = await Promise.all([
|
|
|
+ const [scoreRow, avaliados, porResolvido, porSentimento, porCancelamento, visitas, porSetorRows, pendentes, totalAtendimentos] = await Promise.all([
|
|
|
base().avg("ScoreAtendente as media").whereNotNull("ScoreAtendente").first(),
|
|
|
base().resultSize(),
|
|
|
base().select("Resolvido").count("* as total").groupBy("Resolvido"),
|
|
|
@@ -557,6 +562,7 @@ export async function estatisticasAvaliacoes({ setor, resolvido, sentimento, sta
|
|
|
.select("HorarioVisitaInformado")
|
|
|
.count("* as total")
|
|
|
.groupBy("HorarioVisitaInformado"),
|
|
|
+ precisaJoin ? base().select("a.Setor").count("* as total").groupBy("a.Setor") : Promise.resolve([]),
|
|
|
contarPendentes({ setor }),
|
|
|
setor ? Atendimento.query().where("Setor", setor).resultSize() : Atendimento.query().resultSize()
|
|
|
]);
|
|
|
@@ -571,6 +577,7 @@ export async function estatisticasAvaliacoes({ setor, resolvido, sentimento, sta
|
|
|
sentimento: toMap(porSentimento, "Sentimento"),
|
|
|
cancelamento: toMap(porCancelamento, "StatusCancelamento"),
|
|
|
visitasAgendadas: toMap(visitas, "HorarioVisitaInformado"),
|
|
|
+ porSetor: toMap(porSetorRows, "Setor"),
|
|
|
pendentes,
|
|
|
totalAtendimentos
|
|
|
};
|