novas features, geracao pdf, regras de usuarios, novo perfil de acesso

This commit is contained in:
Vitex Tecnologia
2026-05-13 17:43:25 -03:00
parent 343aae602f
commit 517c9751bc
22 changed files with 1945 additions and 253 deletions
+71 -12
View File
@@ -121,16 +121,25 @@ class FechamentoFechamentosService {
private extractFilenameFromContentDisposition(value: string | undefined): string | null {
if (!value) return null;
const utf8Match = value.match(/filename\*=UTF-8''([^;]+)/i);
const utf8Match = value.match(/filename\*\s*=\s*(?:UTF-8|utf-8)''([^;]+)/i);
if (utf8Match?.[1]) {
try {
return decodeURIComponent(utf8Match[1]);
return decodeURIComponent(utf8Match[1].trim());
} catch {
return utf8Match[1];
return utf8Match[1].trim();
}
}
const regularMatch = value.match(/filename="?([^";]+)"?/i);
return regularMatch?.[1] ?? null;
const regularMatch = value.match(/filename\s*=\s*"([^"]+)"/i) ?? value.match(/filename\s*=\s*([^;\s]+)/i);
return regularMatch?.[1]?.trim() ?? null;
}
private contentDispositionFromHeaders(headers: unknown): string | undefined {
if (!headers || typeof headers !== "object") return undefined;
const h = headers as { get?: (name: string) => string | undefined };
const fromGet = h.get?.("content-disposition") ?? h.get?.("Content-Disposition");
if (fromGet) return fromGet;
const rec = headers as Record<string, string | undefined>;
return rec["content-disposition"] ?? rec["Content-Disposition"];
}
private handleAxiosError(error: unknown, fallback: string): never {
@@ -202,18 +211,28 @@ class FechamentoFechamentosService {
async criarLancamento(
fechamentoId: string,
input: { tipo: "bonus" | "desconto"; descricao: string; pontuacao: number },
input:
| { tipo: "bonus" | "desconto"; descricao: string; pontuacao: number }
| { tipo: "bonus" | "desconto"; descricao: string; valorReal: number },
): Promise<FechamentoTarefaItem> {
try {
const headers = await buildCommanderHeaders();
const baseUrl = resolveCommanderBaseUrl();
const body =
"valorReal" in input
? {
tipo: input.tipo,
descricao: input.descricao,
valorReal: input.valorReal,
}
: {
tipo: input.tipo,
descricao: input.descricao,
pontuacao: input.pontuacao,
};
const response = await axios.post<CriarLancamentoResponse>(
`${baseUrl}/fechamentos/${fechamentoId}/tarefas`,
{
tipo: input.tipo,
descricao: input.descricao,
pontuacao: input.pontuacao,
},
body,
{ headers },
);
return response.data.data;
@@ -268,13 +287,34 @@ class FechamentoFechamentosService {
});
return {
buffer: response.data,
filename: this.extractFilenameFromContentDisposition(response.headers["content-disposition"]),
filename: this.extractFilenameFromContentDisposition(
this.contentDispositionFromHeaders(response.headers),
),
};
} catch (error) {
this.handleAxiosError(error, "Erro ao exportar planilha do fechamento.");
}
}
async exportarPdf(fechamentoId: string): Promise<ExportarPlanilhaResponse> {
try {
const headers = await buildCommanderHeaders();
const baseUrl = resolveCommanderBaseUrl();
const response = await axios.get<ArrayBuffer>(`${baseUrl}/fechamentos/${fechamentoId}/exportar-pdf`, {
headers,
responseType: "arraybuffer",
});
return {
buffer: response.data,
filename: this.extractFilenameFromContentDisposition(
this.contentDispositionFromHeaders(response.headers),
),
};
} catch (error) {
this.handleAxiosError(error, "Erro ao exportar PDF do fechamento.");
}
}
async reabrirFechamento(
fechamentoId: string,
input: { reabertoPorId: string; motivo: string },
@@ -296,6 +336,25 @@ class FechamentoFechamentosService {
}
}
async excluirFechamento(
fechamentoId: string,
input: { excluidoPorId: string; motivo: string },
): Promise<void> {
try {
const headers = await buildCommanderHeaders();
const baseUrl = resolveCommanderBaseUrl();
await axios.delete(`${baseUrl}/fechamentos/${fechamentoId}`, {
headers,
data: {
excluido_por_id: input.excluidoPorId,
motivo: input.motivo.trim(),
},
});
} catch (error) {
this.handleAxiosError(error, "Erro ao excluir fechamento.");
}
}
async reprocessarAsana(fechamentoId: string): Promise<ReprocessarAsanaResponse["data"]> {
try {
const headers = await buildCommanderHeaders();