Skip to main content

Importe Seu Orçamento Anual

Sua equipe financeira acabou de finalizar o orçamento de 2026 em uma planilha. Agora você precisa dele no NovaGestão para previsão de fluxo de caixa e análise de variação. Este guia mostra como importar um ano de dados orçamentários em cerca de 30 minutos.

O que você vai conquistar

Ao final deste guia, você terá:
  • ✅ 12 meses de orçamentos de receita
  • ✅ 12 meses de orçamentos de despesa
  • ✅ Orçamentos alocados por categoria e departamento
  • ✅ Dados de comparação para relatórios de realizado vs. orçado
Tempo: ~30 minutos Dificuldade: Intermediário

Antes de começar

Certifique-se de ter:
  • Uma linha por entrada de orçamento
  • Colunas para: data, valor, descrição, categoria, departamento
  • Valores positivos para receitas, negativos para despesas
As entradas de orçamento referenciam categorias e departamentos por nome. Importe-os primeiro se ainda não o fez.Como importar categorias
Gere uma em Configurações → Chaves API se ainda não tiver.

Exemplo real: Orçamento 2026 da Acme Consultoria

Vamos trabalhar com um exemplo realista. Acme Consultoria é uma empresa de consultoria de software com 15 pessoas que acabou de finalizar seu orçamento de 2026:

Orçamento de receita (simplificado)

  • Contratos recorrentes: R$ 250K/mês
  • Novos projetos: R$ 150K/mês
  • Desaceleração de fim de ano: Queda de 20% na receita em dez-jan

Orçamento de despesa (simplificado)

  • Folha de pagamento: R$ 175K/mês (departamento Operações)
  • Aluguel do escritório: R$ 22,5K/mês (departamento Operações)
  • Marketing: R$ 25K/mês (departamento Vendas & Marketing)
  • Assinaturas de software: R$ 10K/mês (departamento Operações)
Total: 12 orçamentos de receita + 48 orçamentos de despesa = 60 registros

Passo 1: Prepare seus dados

Da planilha para JSON

Veja como fica a planilha de orçamento da Acme:
Mes,Categoria,Departamento,Valor,Descricao
2026-01,Receita de Consultoria,Vendas & Marketing,400000,Contratos recorrentes + novos projetos
2026-01,Folha de Pagamento,Operações,-175000,Salários da equipe
2026-01,Aluguel,Operações,-22500,WeWork Faria Lima
2026-01,Marketing,Vendas & Marketing,-25000,Google Ads + conteúdo
2026-01,Software,Operações,-10000,GitHub + AWS + Slack
2026-02,Receita de Consultoria,Vendas & Marketing,400000,Contratos recorrentes + novos projetos
...
Importante: Os valores dos orçamentos usam a convenção de sinais:
  • Valores positivos = Orçamentos de receita (a receber)
  • Valores negativos = Orçamentos de despesa (a pagar)

Converta para o formato JSON

A API de Importação espera JSON, não CSV. Veja como converter:
// conversor-orcamento.js
const fs = require('fs');
const csv = require('csv-parser');

const orcamentos = [];

fs.createReadStream('orcamento-2026.csv')
  .pipe(csv())
  .on('data', (linha) => {
    orcamentos.push({
      budgeted_date: linha.Mes + '-15',  // Usar meio do mês
      budgeted_amount: linha.Valor,      // Positivo para receita, negativo para despesas
      description: linha.Descricao,
      category_name: linha.Categoria,
      department_name: linha.Departamento  // Opcional: alocação de departamento
    });
  })
  .on('end', () => {
    fs.writeFileSync('orcamentos-2026.json', JSON.stringify(orcamentos, null, 2));
    console.log(`✓ Criado orcamentos-2026.json (${orcamentos.length} registros)`);
  });
Importante: A API determina automaticamente o tipo de orçamento baseado no sinal do valor:
  • Valor positivo → Orçamento de receita (a receber)
  • Valor negativo → Orçamento de despesa (a pagar)
Você pode importar todos os orçamentos (receitas + despesas) em uma única importação.
Execute:
npm install csv-parser
node conversor-orcamento.js

Passo 2: Valide com dry run

Antes de criar orçamentos reais, valide seus dados:
// validar-orcamentos.js
const fs = require('fs');
const API_KEY = process.env.NOVAGESTAO_API_KEY;
const ORG_SLUG = 'acme-consultoria';

async function validarOrcamentos(orcamentos) {
  const response = await fetch('https://api.novagestao.xyz/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${API_KEY}`,
      'X-ORGANIZATION-SLUG': ORG_SLUG,
    },
    body: JSON.stringify({
      query: `
        mutation ValidarOrcamentos($data: [JSON!]!) {
          importCreate(input: {
            data: $data
            entityType: BUDGET
            dryRun: true
          }) {
            success
            validRecords
            invalidRecords
            warnings
            previewData
          }
        }
      `,
      variables: {
        data: orcamentos
      },
    }),
  });

  const result = await response.json();
  const importResult = result.data.importCreate;

  console.log(`\nValidação de Orçamentos:`);
  console.log(`✓ Válidos: ${importResult.validRecords}`);
  console.log(`✗ Inválidos: ${importResult.invalidRecords}`);

  if (importResult.warnings.length > 0) {
    console.log('\n⚠️  Avisos:');
    importResult.warnings.forEach(w => console.log(`  - ${w}`));
  }

  if (importResult.invalidRecords > 0) {
    console.log('\n❌ Erros encontrados:');
    importResult.previewData.forEach((row, i) => {
      if (row._feedback?.status === 'invalid') {
        console.log(`  Linha ${i + 1}: ${row._feedback.errors.join(', ')}`);
      }
    });
    return false;
  }

  return true;
}

async function main() {
  const orcamentos = JSON.parse(fs.readFileSync('orcamentos-2026.json'));

  const isValid = await validarOrcamentos(orcamentos);

  if (isValid) {
    console.log('\n🎉 Todos os orçamentos são válidos! Pronto para importar.');
  } else {
    console.log('\n❌ Corrija os erros acima antes de importar.');
    process.exit(1);
  }
}

main();
Execute:
node validar-orcamentos.js
Saída esperada:
Validação de Orçamentos:
✓ Válidos: 60
✗ Inválidos: 0

🎉 Todos os orçamentos são válidos! Pronto para importar.
Erros comuns de validação:
  • “Category not found” → Verifique se os nomes das categorias correspondem exatamente (sensível a maiúsculas/minúsculas)
  • “Department not found” → Importe os departamentos primeiro
  • “Amount can’t be blank” → Todo orçamento precisa de um budgeted_amount

Passo 3: Importe de verdade

Agora crie a importação real:
// importar-orcamentos.js
const fs = require('fs');
const API_KEY = process.env.NOVAGESTAO_API_KEY;
const ORG_SLUG = 'acme-consultoria';

async function criarImportacao(orcamentos) {
  const response = await fetch('https://api.novagestao.xyz/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${API_KEY}`,
      'X-ORGANIZATION-SLUG': ORG_SLUG,
    },
    body: JSON.stringify({
      query: `
        mutation CriarImportacaoOrcamento($data: [JSON!]!) {
          importCreate(input: {
            data: $data
            entityType: BUDGET
            dryRun: false
          }) {
            success
            import {
              id
              status
              recordsTotal
              entityType
            }
          }
        }
      `,
      variables: { data: orcamentos },
    }),
  });

  const result = await response.json();
  const importData = result.data.importCreate;

  if (!importData.success) {
    throw new Error('Falha na criação da importação');
  }

  console.log(`\n✓ Importação de orçamento criada`);
  console.log(`  ID da Importação: ${importData.import.id}`);
  console.log(`  Registros: ${importData.import.recordsTotal}`);
  console.log(`  Status: ${importData.import.status}`);

  return importData.import.id;
}

async function main() {
  const orcamentos = JSON.parse(fs.readFileSync('orcamentos-2026.json'));

  console.log('🚀 Criando importação de orçamento...\n');

  const importId = await criarImportacao(orcamentos);

  console.log('\n📊 Monitore o progresso:');
  console.log(`  https://app.novagestao.xyz/acme-consultoria/imports/${importId}`);
}

main();
Execute:
node importar-orcamentos.js
Saída esperada:
🚀 Criando importação de orçamento...

✓ Importação de orçamento criada
  ID da Importação: 8f4e3c2a-1b9d-4e7f-8c3a-9d2e1f4c5b6a
  Registros: 60
  Status: pending

📊 Monitore o progresso:
  https://app.novagestao.xyz/acme-consultoria/imports/8f4e3c2a-...
Importação única para todos os orçamentos: Orçamentos de receita e despesa podem ser importados juntos. O sistema determina automaticamente o tipo de orçamento baseado no sinal do valor (positivo = receita, negativo = despesa).

Passo 4: Verifique a importação

Verifique se suas importações foram concluídas com sucesso:
// verificar-status-importacao.js
async function verificarStatus(importId) {
  const response = await fetch('https://api.novagestao.xyz/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${API_KEY}`,
      'X-ORGANIZATION-SLUG': ORG_SLUG,
    },
    body: JSON.stringify({
      query: `
        query ObterImportacao($id: ID!) {
          import(id: $id) {
            id
            status
            progress
            recordsTotal
            recordsProcessed
            recordsCreated
            recordsFailed
            errorMessage
          }
        }
      `,
      variables: { id: importId },
    }),
  });

  const result = await response.json();
  return result.data.import;
}

async function aguardarConclusao(importId) {
  console.log(`\nMonitorando importação de orçamento...`);

  while (true) {
    const importData = await verificarStatus(importId);

    console.log(`  ${importData.progress}% - ${importData.recordsProcessed}/${importData.recordsTotal} processados`);

    if (importData.status === 'completed') {
      console.log(`  ✓ Completo! ${importData.recordsCreated} orçamentos criados`);
      return importData;
    }

    if (importData.status === 'failed') {
      console.log(`  ✗ Falhou: ${importData.errorMessage}`);
      throw new Error('Importação falhou');
    }

    await new Promise(resolve => setTimeout(resolve, 2000));  // Aguardar 2 segundos
  }
}

async function main() {
  const importId = '8f4e3c2a-1b9d-4e7f-8c3a-9d2e1f4c5b6a';

  await aguardarConclusao(importId);

  console.log('\n🎉 Todos os orçamentos importados com sucesso!');
}

main();
Saída esperada:
Monitorando importação de orçamento...
  15% - 9/60 processados
  50% - 30/60 processados
  100% - 60/60 processados
  ✓ Completo! 60 orçamentos criados

🎉 Todos os orçamentos importados com sucesso!

Próximos passos

Visualize no NovaGestão

Navegue até Relatórios → Orçado vs. Realizado para ver seus orçamentos importados comparados com os resultados reais.

Atualize orçamentos no meio do ano

Execute novamente a importação com valores atualizados. Orçamentos com a mesma data+categoria+centro de custo serão atualizados em vez de duplicados.

Automatize importações mensais

Configure um cron job para importar orçamentos atualizados da sua planilha a cada mês.

Importe outras entidades

Experimente importar transações ou faturas em seguida.

Perguntas comuns

Sim! Os orçamentos usam data + valor + contraparte como chave única. Reimportar com a mesma combinação atualiza o orçamento existente.
// Orçamento de receita de janeiro já existe
{ budgeted_date: "2026-01-15", category_name: "Receita de Consultoria", budgeted_amount: "400000" }

// Reimportar com novo valor → atualiza o existente
{ budgeted_date: "2026-01-15", category_name: "Receita de Consultoria", budgeted_amount: "425000" }
Atualmente, as importações de orçamento suportam apenas alocações de categoria e departamento. Alocação de centro de custo não é suportada para orçamentos.Campos de alocação suportados:
  • category_name - Alocação de categoria
  • department_name - Alocação de departamento
Não suportado:
  • cost_center_name - Use alocação de departamento em vez disso
{
  "budgeted_date": "2026-01-15",
  "budgeted_amount": "400000",
  "category_name": "Receita de Consultoria",
  "department_name": "Vendas & Marketing"
}
Sim, use qualquer data dentro do trimestre. Padrão comum:
{ "budgeted_date": "2026-03-15", ...}  // T1
{ "budgeted_date": "2026-06-15", ...}  // T2
{ "budgeted_date": "2026-09-15", ...}  // T3
{ "budgeted_date": "2026-12-15", ...}  // T4
O relatório de fluxo de caixa permite agrupar por trimestre.
Use a mutação budgetDelete:
mutation ExcluirOrcamento($id: ID!) {
  budgetDelete(input: { id: $id }) {
    success
  }
}
Ou exclua todos os orçamentos de um mês/categoria específico pela UI: Planejamento → Orçamentos → Ações em Massa.

Solução de problemas

”Category not found: Receita de Consultoria”

Causa: A categoria não existe na sua organização. Solução: Importe as categorias primeiro, ou verifique erros de digitação (nomes são sensíveis a maiúsculas/minúsculas).
// Importar categoria faltante
await fetch('https://api.novagestao.xyz/graphql', {
  // ... headers
  body: JSON.stringify({
    query: `
      mutation {
        importCreate(input: {
          data: [{ name: "Receita de Consultoria", code: "CONSULTORIA", category_type: "revenue" }]
          entityType: CATEGORY
        }) { success }
      }
    `
  })
});

”Amount is required”

Causa: Campo budgeted_amount ausente ou zero. Solução: Certifique-se de que cada orçamento tenha um valor válido com o sinal correto:
// Receita (positivo)
{ budgeted_amount: "400000" }

// Despesa (negativo)
{ budgeted_amount: "-175000" }

Importação travada em “pending” por >5 minutos

Causa: Lote grande ou carga do sistema. Solução: Aguarde um pouco mais (até 15 minutos para 1000+ registros). Ou verifique erros:
query {
  import(id: "seu-id-de-importacao") {
    status
    errorMessage
    recordsFailed
  }
}
Se recordsFailed > 0, alguns registros tiveram problemas. Verifique os erros de registros individuais na UI.

Script completo

Quer o código completo funcionando? Aqui está tudo em um arquivo:
// Importe orçamentos diretamente do Google Sheets
// 1. No Google Sheets, vá em Extensões → Apps Script
// 2. Cole este código
// 3. Defina API_KEY e ORG_SLUG nas propriedades do script (Arquivo → Propriedades do projeto)
// 4. Execute a função importarOrcamentosDaPlanilha()

function importarOrcamentosDaPlanilha() {
  const API_KEY = PropertiesService.getScriptProperties().getProperty('NOVAGESTAO_API_KEY');
  const ORG_SLUG = PropertiesService.getScriptProperties().getProperty('ORG_SLUG');

  // Obter planilha ativa
  const planilha = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const dados = planilha.getDataRange().getValues();

  // Pular linha de cabeçalho, converter para objetos de orçamento
  const orcamentos = dados.slice(1).map(linha => ({
    budgeted_date: Utilities.formatDate(new Date(linha[0]), 'GMT', 'yyyy-MM') + '-15',
    category_name: linha[1],
    department_name: linha[2],
    budgeted_amount: String(linha[3]),  // Positivo para receita, negativo para despesa
    description: linha[4]
  }));

  // Chamar API NovaGestão
  const response = UrlFetchApp.fetch('https://api.novagestao.xyz/graphql', {
    method: 'post',
    contentType: 'application/json',
    headers: {
      'Authorization': 'Bearer ' + API_KEY,
      'X-ORGANIZATION-SLUG': ORG_SLUG
    },
    payload: JSON.stringify({
      query: `
        mutation($data: [JSON!]!) {
          importCreate(input: {
            data: $data
            entityType: BUDGET
            dryRun: false
          }) {
            success
            import { id status recordsTotal }
            errors { message }
          }
        }
      `,
      variables: { data: orcamentos }
    })
  });

  const resultado = JSON.parse(response.getContentText());

  if (resultado.data.importCreate.success) {
    const importId = resultado.data.importCreate.import.id;
    Logger.log('✓ Importação criada: ' + importId);
    SpreadsheetApp.getUi().alert('Importação de orçamento criada com sucesso!\n\nID da Importação: ' + importId);
  } else {
    Logger.log('✗ Importação falhou: ' + resultado.data.importCreate.errors[0].message);
    SpreadsheetApp.getUi().alert('Importação falhou: ' + resultado.data.importCreate.errors[0].message);
  }
}

// Estrutura esperada da planilha:
// | Mês        | Categoria              | Departamento      | Valor   | Descrição                            |
// | 2026-01-01 | Receita de Consultoria | Vendas & Marketing| 400000  | Contratos recorrentes + novos projetos|
// | 2026-01-01 | Folha de Pagamento     | Operações         | -175000 | Salários da equipe                   |

Usando Google Sheets (Recomendado)

A maneira mais fácil de importar orçamentos é diretamente do Google Sheets:
  1. Abra sua planilha de orçamento no Google Sheets
  2. Vá em Extensões → Apps Script
  3. Cole o código Google Apps Script acima
  4. Defina suas credenciais da API em Arquivo → Propriedades do projeto → Propriedades do script:
    • NOVAGESTAO_API_KEY: Sua chave API
    • ORG_SLUG: Slug da sua organização
  5. Execute a função importarOrcamentosDaPlanilha()

Usando Node.js

Se você preferir executar localmente ou tiver dados em arquivos CSV:
npm install csv-parser
node importador-orcamento.js

Precisa de ajuda? Veja o guia de solução de problemas ou contate o suporte.