import axios from "axios"; import { buildCommanderHeaders, resolveCommanderBaseUrl } from "./commanderHttp"; export type CompetenciaStatus = "em_aberto" | "concluido"; export type CompetenciaItem = { id: string; mes: number; ano: number; status: CompetenciaStatus; quantidadeFechamentos: number; criadoEm: string; atualizadoEm: string; }; export type FechamentoDaCompetenciaItem = { id: string; competenciaId: string; parceiroId: string; parceiroNome: string; parceiroCodinome: string | null; parceiroLogoUrl: string | null; parceiroFator?: number | null; horasTotal: number; status: "em_aberto" | "fechado"; versao: number; pontuacaoTotalEntregue: number; pontuacaoAprovada: number; pontuacaoMeta: number; pontuacaoPaga: number; pontuacaoBanco: number; exportadoFinanceiro: boolean; fechadoPorId: string | null; fechadoEm: string | null; criadoEm: string; atualizadoEm: string; }; type ListarCompetenciasResponse = { data: CompetenciaItem[]; }; type ListarFechamentosDaCompetenciaResponse = { data: FechamentoDaCompetenciaItem[]; }; type CriarCompetenciaResponse = { data: CompetenciaItem; }; type ConcluirCompetenciaResponse = { data: CompetenciaItem & { concluidoPorNome: string | null; }; }; type ReabrirCompetenciaResponse = { data: CompetenciaItem & { reabertoPorNome: string | null; }; }; type ImportarCompetenciaResponse = { data: { competenciaId: string; tarefasRecebidas: number; tarefasImportadas: number; fechamentosCriados: number; tarefasIgnoradasSemParceiro: number; chamadasSubtarefasAsana: number; }; }; export type ImportacaoAsanaModo = | "reprocessar_tudo" | "reprocessar_alguns" | "buscar_novos_fechamentos"; type ApiErrorShape = { error?: { message?: string; }; }; class FechamentoCompetenciasService { private handleAxiosError(error: unknown, fallback: string): never { if (axios.isAxiosError(error)) { if (!error.response) { throw new Error( "Não foi possível conectar na API do Commander. Verifique VITE_API_BASE_URL_COMMANDER e se o backend está acessível.", ); } const message = ((error.response.data as ApiErrorShape | undefined)?.error?.message ?? error.message ?? fallback) as string; throw new Error(message); } throw new Error(fallback); } async listarCompetencias(params: { ano?: number; status?: CompetenciaStatus }): Promise { try { const headers = await buildCommanderHeaders(); const baseUrl = resolveCommanderBaseUrl(); const response = await axios.get(`${baseUrl}/competencias`, { headers, params: { ano: params.ano, status: params.status, }, }); return response.data.data ?? []; } catch (error) { this.handleAxiosError(error, "Erro ao listar competências."); } } async listarFechamentosDaCompetencia(competenciaId: string): Promise { try { const headers = await buildCommanderHeaders(); const baseUrl = resolveCommanderBaseUrl(); const response = await axios.get( `${baseUrl}/competencias/${competenciaId}/fechamentos`, { headers }, ); return response.data.data ?? []; } catch (error) { this.handleAxiosError(error, "Erro ao listar fechamentos da competência."); } } async criarCompetencia(input: { mes: number; ano: number }): Promise { try { const headers = await buildCommanderHeaders(); const baseUrl = resolveCommanderBaseUrl(); const response = await axios.post( `${baseUrl}/competencias`, { mes: input.mes, ano: input.ano }, { headers }, ); return response.data.data; } catch (error) { this.handleAxiosError(error, "Erro ao criar competência."); } } async concluirCompetencia(competenciaId: string, concluidoPorId: string): Promise { try { const headers = await buildCommanderHeaders(); const baseUrl = resolveCommanderBaseUrl(); const response = await axios.post( `${baseUrl}/competencias/${competenciaId}/concluir`, { concluido_por_id: concluidoPorId }, { headers }, ); return response.data.data; } catch (error) { this.handleAxiosError(error, "Erro ao concluir competência."); } } async reabrirCompetencia( competenciaId: string, reabertoPorId: string, motivo: string, ): Promise { try { const headers = await buildCommanderHeaders(); const baseUrl = resolveCommanderBaseUrl(); const response = await axios.post( `${baseUrl}/competencias/${competenciaId}/reabrir`, { reaberto_por_id: reabertoPorId, motivo: motivo.trim() }, { headers }, ); return response.data.data; } catch (error) { this.handleAxiosError(error, "Erro ao reabrir competência."); } } async excluirCompetencia(competenciaId: string, excluidoPorId: string): Promise { try { const headers = await buildCommanderHeaders(); const baseUrl = resolveCommanderBaseUrl(); await axios.delete(`${baseUrl}/competencias/${competenciaId}`, { headers, data: { excluido_por_id: excluidoPorId }, }); } catch (error) { this.handleAxiosError(error, "Erro ao excluir competência."); } } async importarDoAsana( competenciaId: string, opcoes?: { modo?: ImportacaoAsanaModo; parceiroIds?: string[] }, ): Promise<{ tarefasRecebidas: number; tarefasImportadas: number; fechamentosCriados: number; tarefasIgnoradasSemParceiro: number }> { try { const headers = await buildCommanderHeaders(); const baseUrl = resolveCommanderBaseUrl(); const response = await axios.post( `${baseUrl}/competencias/${competenciaId}/importar`, { modo: opcoes?.modo ?? "reprocessar_tudo", parceiroIds: opcoes?.parceiroIds, }, { headers }, ); return { tarefasRecebidas: response.data.data.tarefasRecebidas, tarefasImportadas: response.data.data.tarefasImportadas, fechamentosCriados: response.data.data.fechamentosCriados, tarefasIgnoradasSemParceiro: response.data.data.tarefasIgnoradasSemParceiro, }; } catch (error) { this.handleAxiosError(error, "Erro ao importar tasks do Asana."); } } } export const fechamentoCompetenciasService = new FechamentoCompetenciasService();