arcadiasuite/server/plus/client.ts

377 lines
11 KiB
TypeScript

const PLUS_PORT = process.env.PLUS_PORT || 8080;
const PLUS_BASE_URL = `http://localhost:${PLUS_PORT}`;
export interface PlusApiResponse<T = any> {
success: boolean;
data?: T;
error?: string;
message?: string;
}
async function plusFetch<T = any>(
endpoint: string,
options: RequestInit = {},
empresaId?: number
): Promise<PlusApiResponse<T>> {
try {
const headers: Record<string, string> = {
"Content-Type": "application/json",
Accept: "application/json",
...(options.headers as Record<string, string> || {}),
};
if (empresaId) {
headers["X-Empresa-Id"] = String(empresaId);
}
const response = await fetch(`${PLUS_BASE_URL}${endpoint}`, {
...options,
headers,
});
const data = await response.json();
if (!response.ok) {
return {
success: false,
error: data.message || `HTTP ${response.status}`,
};
}
return { success: true, data };
} catch (error: any) {
return {
success: false,
error: error.message || "Erro de conexão com Plus",
};
}
}
export interface PlusCliente {
id?: number;
razao_social: string;
nome_fantasia?: string;
cpf_cnpj?: string;
ie?: string;
telefone?: string;
celular?: string;
email?: string;
cep?: string;
logradouro?: string;
numero?: string;
bairro?: string;
cidade?: string;
uf?: string;
}
export interface PlusProduto {
id?: number;
nome: string;
referencia?: string;
valor_venda: number;
NCM?: string;
unidade?: string;
estoque_atual?: number;
codigo_barras?: string;
categoria_id?: number;
}
export interface PlusVenda {
id?: number;
cliente_id?: number;
natureza_operacao_id?: number;
valor_total: number;
desconto?: number;
forma_pagamento?: string;
observacao?: string;
itens: PlusVendaItem[];
faturar?: {
forma_pagamento: string;
valor: number;
parcelas?: number;
}[];
}
export interface PlusVendaItem {
produto_id: number;
quantidade: number;
valor_unitario: number;
desconto?: number;
valor_total: number;
}
export interface PlusContaReceber {
id?: number;
cliente_id?: number;
venda_id?: number;
data_vencimento: string;
valor: number;
valor_recebido?: number;
status?: string;
forma_pagamento?: string;
observacao?: string;
}
export interface PlusEstoqueMovimento {
produto_id: number;
tipo: "entrada" | "saida";
quantidade: number;
valor_unitario?: number;
observacao?: string;
}
export interface PlusNFeData {
venda_id?: number;
cliente_id?: number;
natureza_operacao?: string;
itens: Array<{
produto_id: number;
quantidade: number;
valor_unitario: number;
ncm?: string;
cfop?: string;
}>;
pagamentos?: Array<{
forma: string;
valor: number;
}>;
}
export const plusClient = {
async getDashboardData(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/graficos/dados-cards", {}, empresaId);
},
async getVendasMes(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/graficos/grafico-vendas-mes", {}, empresaId);
},
async getComprasMes(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/graficos/grafico-compras-mes", {}, empresaId);
},
async getGraficoMes(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/graficos/grafico-mes", {}, empresaId);
},
async getContasReceber(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/graficos/grafico-conta-receber", {}, empresaId);
},
async getContasPagar(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/graficos/grafico-conta-pagar", {}, empresaId);
},
async getContasEmpresa(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/contas-empresa", {}, empresaId);
},
async healthCheck(): Promise<PlusApiResponse> {
return plusFetch("/api/health");
},
// ========================================
// CLIENTES
// ========================================
async listarClientes(empresaId?: number, page = 1): Promise<PlusApiResponse<PlusCliente[]>> {
return plusFetch(`/api/clientes?page=${page}`, {}, empresaId);
},
async criarCliente(data: PlusCliente, empresaId?: number): Promise<PlusApiResponse<PlusCliente>> {
return plusFetch("/api/clientes", {
method: "POST",
body: JSON.stringify(data),
}, empresaId);
},
async atualizarCliente(id: number, data: Partial<PlusCliente>, empresaId?: number): Promise<PlusApiResponse<PlusCliente>> {
return plusFetch(`/api/clientes/${id}`, {
method: "PUT",
body: JSON.stringify(data),
}, empresaId);
},
async buscarCliente(id: number, empresaId?: number): Promise<PlusApiResponse<PlusCliente>> {
return plusFetch(`/api/clientes/${id}`, {}, empresaId);
},
// ========================================
// FORNECEDORES
// ========================================
async listarFornecedores(empresaId?: number, page = 1): Promise<PlusApiResponse> {
return plusFetch(`/api/fornecedores?page=${page}`, {}, empresaId);
},
async criarFornecedor(data: any, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/fornecedores", {
method: "POST",
body: JSON.stringify(data),
}, empresaId);
},
// ========================================
// PRODUTOS
// ========================================
async listarProdutos(empresaId?: number, page = 1): Promise<PlusApiResponse<PlusProduto[]>> {
return plusFetch(`/api/produtos?page=${page}`, {}, empresaId);
},
async criarProduto(data: PlusProduto, empresaId?: number): Promise<PlusApiResponse<PlusProduto>> {
return plusFetch("/api/produtos", {
method: "POST",
body: JSON.stringify(data),
}, empresaId);
},
async atualizarProduto(id: number, data: Partial<PlusProduto>, empresaId?: number): Promise<PlusApiResponse<PlusProduto>> {
return plusFetch(`/api/produtos/${id}`, {
method: "PUT",
body: JSON.stringify(data),
}, empresaId);
},
async buscarProduto(id: number, empresaId?: number): Promise<PlusApiResponse<PlusProduto>> {
return plusFetch(`/api/produtos/${id}`, {}, empresaId);
},
// ========================================
// VENDAS
// ========================================
async listarVendas(empresaId?: number, page = 1, filtros?: Record<string, string>): Promise<PlusApiResponse> {
const params = new URLSearchParams({ page: String(page), ...filtros });
return plusFetch(`/api/vendas?${params}`, {}, empresaId);
},
async criarVenda(data: PlusVenda, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/vendas", {
method: "POST",
body: JSON.stringify(data),
}, empresaId);
},
async buscarVenda(id: number, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch(`/api/vendas/${id}`, {}, empresaId);
},
async cancelarVenda(id: number, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch(`/api/vendas/${id}/cancelar`, {
method: "POST",
}, empresaId);
},
// ========================================
// ESTOQUE
// ========================================
async consultarEstoque(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/estoque", {}, empresaId);
},
async movimentarEstoque(data: PlusEstoqueMovimento, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/estoque/movimentar", {
method: "POST",
body: JSON.stringify(data),
}, empresaId);
},
async ajustarEstoque(produtoId: number, quantidade: number, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch(`/api/estoque/ajustar`, {
method: "POST",
body: JSON.stringify({ produto_id: produtoId, quantidade }),
}, empresaId);
},
// ========================================
// CONTAS A RECEBER
// ========================================
async listarContasReceber(empresaId?: number, filtros?: Record<string, string>): Promise<PlusApiResponse<PlusContaReceber[]>> {
const params = filtros ? `?${new URLSearchParams(filtros)}` : "";
return plusFetch(`/api/contas-receber${params}`, {}, empresaId);
},
async criarContaReceber(data: PlusContaReceber, empresaId?: number): Promise<PlusApiResponse<PlusContaReceber>> {
return plusFetch("/api/contas-receber", {
method: "POST",
body: JSON.stringify(data),
}, empresaId);
},
async receberConta(id: number, data: { valor_recebido: number; data_recebimento: string }, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch(`/api/contas-receber/${id}/receber`, {
method: "POST",
body: JSON.stringify(data),
}, empresaId);
},
// ========================================
// CONTAS A PAGAR
// ========================================
async listarContasPagar(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/contas-pagar", {}, empresaId);
},
// ========================================
// FISCAL - NF-e / NFC-e
// ========================================
async emitirNFe(dados: PlusNFeData, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/nfe/emitir", {
method: "POST",
body: JSON.stringify(dados),
}, empresaId);
},
async emitirNFCe(dados: PlusNFeData, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/nfce/emitir", {
method: "POST",
body: JSON.stringify(dados),
}, empresaId);
},
async consultarNFe(chave: string, empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/nfe/consultar", {
method: "POST",
body: JSON.stringify({ chave }),
}, empresaId);
},
async listarNFes(empresaId?: number, page = 1): Promise<PlusApiResponse> {
return plusFetch(`/api/nfe?page=${page}`, {}, empresaId);
},
// ========================================
// EMPRESAS
// ========================================
async listarEmpresas(): Promise<PlusApiResponse> {
return plusFetch("/api/empresas");
},
async buscarEmpresa(id: number): Promise<PlusApiResponse> {
return plusFetch(`/api/empresas/${id}`);
},
// ========================================
// NATUREZAS DE OPERAÇÃO
// ========================================
async listarNaturezasOperacao(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/natureza-operacao", {}, empresaId);
},
// ========================================
// CATEGORIAS
// ========================================
async listarCategorias(empresaId?: number): Promise<PlusApiResponse> {
return plusFetch("/api/categorias", {}, empresaId);
},
};
export default plusClient;