Dashboard
Visão estratégica e operacional
🔴 Manutenções vencidas — clientes que não retornaram
🟡 Manutenções nos próximos 7 dias
🏆 Ranking VIP — maiores LTVs
📊 Sazonalidade mensal
🎯 Origem dos clientes
📦 Produtos mais vendidos
🎂 Aniversariantes do mês
😴 Clientes sumidos (+90 dias)
Base de Clientes
—
Cliente
Telefone
Cidade / Bairro
Origem
Status
Ações
Central de Reativação
Segmentação inteligente
Produtos & Serviços
Catálogo completo
Pesquisa por Produto
Veja quem comprou cada produto ou serviço
Satisfação — NPS
Net Promoter Score da sua base
Cliente
NPS
Classificação
Ação
Aniversários
Clientes que fazem aniversário este mês
Configurações
Integração e preferências
🔗 Google Sheets
Um único Google Sheets com 6 abas (criadas automaticamente pelo script):
CRM:
Financeiro:
Um único Apps Script serve tudo — cole o script na aba Extensions > Apps Script e publique como Web App.
CRM:
clientes · compras · produtos · leads · configFinanceiro:
transacoes: id|tipo|valor|data|cliente|tipoVenda|tipoDespesa|categoria|forma|obsUm único Apps Script serve tudo — cole o script na aba Extensions > Apps Script e publique como Web App.
🔐 Senha
Padrão:
A senha é salva no Google Sheets (aba
admin123A senha é salva no Google Sheets (aba
config) e sincroniza em todos os dispositivos automaticamente. Se o Sheets não estiver configurado, fica salva só neste navegador.Exigir senha para entrar
Se desativado, o sistema abre direto, sem pedir senha.
🧹 Limpar Cache
Se o sistema travar ou não carregar, use este botão para limpar o cache do navegador e reiniciar.
💬 Mensagens do WhatsApp
Personalize as mensagens enviadas pelo sistema. Use
{nome} para inserir o nome do cliente automaticamente.// ═══════════════════════════════════════════════════════════════════
// APPS SCRIPT UNIFICADO — Sistema Completo (CRM + Financeiro)
// Cole este código em Extensions > Apps Script do seu Google Sheets
// Publique como: Deploy > New Deployment > Web App
// Execute as: Me | Who has access: Anyone
// ═══════════════════════════════════════════════════════════════════
const SS = SpreadsheetApp.getActiveSpreadsheet();
// ── Utilitário: pega ou cria aba ─────────────────────────────────
function getSheet(name) {
let sheet = SS.getSheetByName(name);
if (!sheet) {
sheet = SS.insertSheet(name);
// Adiciona cabeçalhos padrão por aba
const headers = {
clientes: ['id','nome','telefone','email','cidade','bairro','aniversario','origem','interesse','tags','status','nps','depoimento','ultimoContato','cadastroEm','obs'],
compras: ['id','clienteId','produto','data','valor','formaPagamento','vendedor','proximaManutencao','frequencia','obs'],
produtos: ['id','nome','categoria','descricao','preco','custo','margem','frequencia','status','tags','cadastroEm'],
leads: ['id','nome','telefone','origem','cidade','interesse','valor','coluna','proxAcao','proxData','motivo','obs','criadoEm','log'],
config: ['chave','valor'],
transacoes: ['id','tipo','valor','data','cliente','tipoVenda','tipoDespesa','categoria','forma','obs'],
};
if (headers[name]) sheet.appendRow(headers[name]);
}
return sheet;
}
// ── Lê aba como array de objetos ─────────────────────────────────
function readSheet(name) {
const sheet = SS.getSheetByName(name);
if (!sheet) return [];
const rows = sheet.getDataRange().getValues();
if (rows.length < 2) return [];
const headers = rows[0];
return rows.slice(1).map(r => {
const o = {};
headers.forEach((h, i) => o[h] = r[i]);
return o;
});
}
// ── Salvar linha ─────────────────────────────────────────────────
function saveRow(sheetName, row) {
getSheet(sheetName).appendRow(row);
}
// ── Editar linha por ID ──────────────────────────────────────────
function editRow(sheetName, id, row) {
const sheet = getSheet(sheetName);
const rows = sheet.getDataRange().getValues();
for (let i = 1; i < rows.length; i++) {
if (String(rows[i][0]) === String(id)) {
sheet.getRange(i + 1, 1, 1, row.length).setValues([row]);
return;
}
}
}
// ── Deletar linha por ID ─────────────────────────────────────────
function deleteRow(sheetName, id) {
const sheet = SS.getSheetByName(sheetName);
if (!sheet) return;
const rows = sheet.getDataRange().getValues();
for (let i = 1; i < rows.length; i++) {
if (String(rows[i][0]) === String(id)) {
sheet.deleteRow(i + 1);
return;
}
}
}
// ── Resposta JSON ────────────────────────────────────────────────
function jsonResp(data) {
return ContentService
.createTextOutput(JSON.stringify(data))
.setMimeType(ContentService.MimeType.JSON);
}
// ═══════════════════════════════════════════════════════════════════
// doGet — CRM (payload base64) + Financeiro (GET simples por sheet)
// ═══════════════════════════════════════════════════════════════════
function doGet(e) {
try {
// ── CRM: payload base64 ──────────────────────────────────────
if (e.parameter && e.parameter.payload) {
const data = JSON.parse(
Utilities.newBlob(
Utilities.base64Decode(e.parameter.payload, Utilities.Charset.UTF_8)
).getDataAsString()
);
const sheetName = data.sheet || 'clientes';
if (data.action === 'salvar') {
saveRow(sheetName, data.row);
return jsonResp({ ok: true });
}
if (data.action === 'editar') {
editRow(sheetName, data.id, data.row);
return jsonResp({ ok: true });
}
if (data.action === 'deletar') {
deleteRow(sheetName, data.id);
return jsonResp({ ok: true });
}
// salvar_todos (Kanban bulk save — não usado mais, mas por segurança)
if (data.action === 'salvar_todos') {
return jsonResp({ ok: true });
}
}
// ── Leitura simples por ?sheet=nome ─────────────────────────
const which = (e.parameter && e.parameter.sheet) || 'clientes';
return jsonResp(readSheet(which));
} catch (err) {
return jsonResp({ ok: false, error: err.message });
}
}
// ═══════════════════════════════════════════════════════════════════
// doPost — Financeiro (JSON no body: { action, id, tipo, valor, ... })
// ═══════════════════════════════════════════════════════════════════
function doPost(e) {
try {
const data = JSON.parse(e.postData.contents);
const sheet = data.sheet || 'transacoes';
// ── Salvar transação ─────────────────────────────────────────
if (data.action === 'salvar') {
const row = [
data.id, data.tipo, data.valor, data.data,
data.cliente || '', data.tipoVenda || '',
data.tipoDespesa || '', data.categoria || '',
data.forma || '', data.obs || ''
];
saveRow(sheet, row);
return jsonResp({ ok: true });
}
// ── Deletar transação ────────────────────────────────────────
if (data.action === 'deletar') {
deleteRow(sheet, data.id);
return jsonResp({ ok: true });
}
// ── Editar transação ─────────────────────────────────────────
if (data.action === 'editar') {
const row = [
data.id, data.tipo, data.valor, data.data,
data.cliente || '', data.tipoVenda || '',
data.tipoDespesa || '', data.categoria || '',
data.forma || '', data.obs || ''
];
editRow(sheet, data.id, row);
return jsonResp({ ok: true });
}
return jsonResp({ ok: false, error: 'Ação não reconhecida: ' + data.action });
} catch (err) {
return jsonResp({ ok: false, error: err.message });
}
}
Kanban de Leads
Pipeline de prospecção e aquisição
Novo Lead
Identificação
Próxima Ação
—
—
Mover este lead para outra etapa do funil:
Dashboard
Visão geral do seu financeiro
Entradas
R$ 0
0 vendas
Saídas
R$ 0
0 despesas
Lucro
R$ 0
margem 0%
Ticket médio
R$ 0
por venda
Entradas por categoria
Saídas por categoria
Entradas por tipo de venda
Evolução financeira mensal
Novo lançamento
Registre entradas e saídas
Histórico
Todos os lançamentos
Total filtrado
R$ 0
Data
Descrição
Categoria
Tipo / Despesa
Forma
Valor
Análise de Despesas
Gastos por tipo, mês a mês
Composição das despesas por mês
Balanço Anual
Resultado mês a mês
Mês
Saldo Ant.
Entradas
Saídas
Saldo
Evolução mensal detalhada
Metas & Pricing
Precificação inteligente, metas e destino real do lucro
Configurar meta do mês
Progresso — Faturamento
—
—
Progresso — Lucro Líquido
—
—
O que fazer para bater a meta
Configure a meta acima.
Concentração de receita
Carregando...
Contas a Pagar
Obrigações futuras, vencimentos e controle de pagamento
Nova obrigação
Nenhuma obrigação cadastrada.
DRE — Demonstração do Resultado
Calculada automaticamente a partir dos seus lançamentos
DFC — Demonstração dos Fluxos de Caixa
Método direto — classificação por tipo de movimentação
BP — Balanço Patrimonial
Caixa e contas a pagar preenchidos automaticamente — complete o restante
Como funciona: O caixa é calculado dos seus lançamentos. Contas a Pagar vem do módulo CAP. Os demais campos (imobilizado, estoque, empréstimos, capital) você preenche manualmente. Os dados ficam salvos no navegador.
ATIVO
Ativo Circulante
Caixa e equivalentes (auto)
R$ 0,00
Contas a receber
Estoque
Outros circulantes
Total Ativo Circulante
R$ 0,00
Ativo Não Circulante
Imobilizado (equipamentos)
Depreciação acumulada (-)
Outros não circulantes
Total Ativo Não Circulante
R$ 0,00
TOTAL DO ATIVO
R$ 0,00
PASSIVO + PATRIMÔNIO LÍQUIDO
Passivo Circulante
Contas a pagar (auto)
R$ 0,00
Empréstimos CP
Impostos a recolher
Outros passivos CP
Total Passivo Circulante
R$ 0,00
Passivo Não Circulante
Empréstimos LP
Outros passivos LP
Total Passivo Não Circulante
R$ 0,00
Patrimônio Líquido
Capital social
Lucros acumulados (auto)
R$ 0,00
Reservas
Total PL
R$ 0,00
TOTAL PASSIVO + PL
R$ 0,00