novas features, geracao pdf, regras de usuarios, novo perfil de acesso
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user