Personalização e Configuração
Este guia explica como personalizar e configurar o OmniCRM para corresponder à sua identidade de marca, requisitos operacionais e necessidades de integração.
Variáveis de Ambiente (.env)
O OmniCRM usa variáveis de ambiente para configurar tanto a API de backend quanto a interface do usuário de frontend. Existem dois arquivos .env separados que controlam diferentes aspectos do sistema.
Configuração da API de Backend (.env)
Localizado na raiz do diretório do OmniCRM, este arquivo configura conexões de banco de dados e integração com CGRates.
Localização: /OmniCRM/.env
Configuração do Banco de Dados:
# Banco de Dados MySQL/MariaDB (Dados do CRM)
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_USER=omnitouch
MYSQL_PASSWORD=your_database_password
MYSQL_DATABASE=crm
DB_SERVER=db
# Banco de Dados PostgreSQL (Dados do CGRates)
POSTGRES_USER=cgrates
POSTGRES_PASSWORD=cgrates_password
POSTGRES_DB=cgrates_db
Configuração do CGRates:
# Credenciais da API do CGRates
CGRATES_API_USER=admin
CGRATES_API_PASS=secret
CGRATES_DB_USER=cgrates
CGRATES_DB_PASS=cgrates_password
CGRATES_DB_NAME=cgrates_db
CGRATES_DB_PORT=5432
Considerações de Segurança:
- Nunca comite arquivos .env no controle de versão - Use
.env.examplecomo um modelo - Use senhas fortes - Mínimo de 16 caracteres com letras maiúsculas e minúsculas, números e símbolos
- Rotacione credenciais regularmente - Especialmente para implantações em produção
- Restrinja o acesso ao banco de dados - Use listas brancas de IP e regras de firewall
Configuração da Interface do Usuário de Frontend (.env)
Localizado no diretório OmniCRM-UI, este arquivo controla a marca, aparência, integrações e flags de recursos.
Localização: /OmniCRM/OmniCRM-UI/.env
Chaves da API e Integração:
# API do Google Maps (para autocompletar endereços e geocodificação)
REACT_APP_GOOGLE_API_KEY=your_google_api_key
# Gateway de Pagamento Stripe
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
# Desabilitar auto-lançamento do navegador ao iniciar npm
BROWSER=none
Informações de Marca e Empresa:
# Marca da Empresa
REACT_APP_COMPANY_NAME="ShellFone"
REACT_APP_PORTAL_NAME="ShellManager"
REACT_APP_SELF_CARE_NAME="ShellCare"
REACT_APP_COMPANY_TAGLINE="Phones with Shells"
Esses valores aparecem em toda a interface:
COMPANY_NAME- Exibido em títulos de página, e-mails e comunicações com clientesPORTAL_NAME- Nome do portal de administração/equipe (por exemplo, "ShellManager")SELF_CARE_NAME- Nome do portal de autoatendimento do cliente (por exemplo, "ShellCare")COMPANY_TAGLINE- Aparece em telas de login e materiais de marketing
Localização e Configurações Regionais:
# Idioma e Localidade
# Idiomas suportados: ar, ch, en, fr, gr, it, ru, sp
REACT_APP_DEFAULT_LANGUAGE=en
REACT_APP_LOCALE="en-GB"
# Localização Padrão (para autocompletar endereços)
REACT_APP_DEFAULT_LOCATION="Sydney, Australia"
REACT_APP_DEFAULT_COUNTRY="Australia"
# Configurações de Moeda
REACT_APP_CURRENCY_CODE="GBP"
REACT_APP_CURRENCY_SYMBOL="£"
Personalização do Esquema de Cores:
# Cor Primária (cor principal da marca)
REACT_APP_PRIMARY_COLOR=#405189
# Opções de Cores Adicionais (exemplos comentados)
# REACT_APP_SECONDARY_COLOR=#2bFFcf
# REACT_APP_TERTIARY_COLOR=#1a9fbf
# REACT_APP_SUCCESS_COLOR=#28a745
# REACT_APP_INFO_COLOR=#17a2b8
# REACT_APP_WARNING_COLOR=#ffc107
# REACT_APP_DANGER_COLOR=#dc3545
A cor primária é aplicada a:
- Cabeçalhos de navegação
- Botões de ação
- Links e destaques
- Estados ativos
- Elementos de marca
Integrações de Aplicativos Web:
Configure até 6 aplicativos web de acesso rápido que aparecem no painel de administração:
# Aplicativo Web 1: GitHub
REACT_APP_WEB_APP_1_NAME="GitHub"
REACT_APP_WEB_APP_1_URL="https://github.com"
REACT_APP_WEB_APP_1_ICON_PATH="resources/webapp_icons/github.png"
# Aplicativo Web 2: Xero
REACT_APP_WEB_APP_2_NAME="Xero"
REACT_APP_WEB_APP_2_URL="https://go.xero.com/"
REACT_APP_WEB_APP_2_ICON_PATH="resources/webapp_icons/xero.png"
# Aplicativo Web 3-6: Integrações adicionais
# (Configure de forma semelhante com NAME, URL e ICON_PATH)
Monitoramento e Análise:
# Integração do Painel Grafana
REACT_APP_GRAFANA_URLS=url1,url2,url3
REACT_APP_GRAFANA_LABELS=label1,label2,label3
REACT_APP_GRAFANA_API_KEY=your-api-key
Flags de Recursos:
# URLs de Suporte e Documentação
REACT_APP_FAQS_URL=https://docs.yourcompany.com/faqs
REACT_APP_SUPPORT_URL=https://support.yourcompany.com
# Login Social (Google, Facebook, etc.)
REACT_APP_ALLOW_SOCIAL_LOGINS=yes
Personalização do Logo e Imagem de Splash
O OmniCRM permite que você substitua as imagens de marca padrão pelo logo e telas de splash da sua empresa sem modificar o código.
Arquivos de Logo
Os logos são armazenados em /OmniCRM-UI/src/assets/images/omnitouch/ e usam um sistema de fallback:
Logos Padrão (sempre presentes):
DefaultLogoDark.png- Logo do tema escuro (usado em fundos claros)DefaultLogoLight.png- Logo do tema claro (usado em fundos escuros)
Logos Personalizados (opcionais, têm precedência quando presentes):
logoSm.png- Logo pequeno para barra lateral colapsada (recomendado: 100x100px)logoDark.png- Logo escuro em tamanho real para cabeçalhos (recomendado: 200x50px)logoLight.png- Logo claro em tamanho real para telas de autenticação (recomendado: 200x50px)
Como Funciona o Fallback do Logo:
O sistema tenta carregar logos personalizados primeiro. Se um arquivo de logo personalizado não existir, ele recorre ao padrão:
// De Header.js
const tryImport = (filename) => {
try {
return require(`../assets/images/omnitouch/${filename}`);
} catch (err) {
return null; // Recorre ao padrão
}
};
const userLogoSm = tryImport("logoSm.png");
const userLogoDark = tryImport("logoDark.png");
const userLogoLight = tryImport("logoLight.png");
Onde os Logos Aparecem:
- logoSm.png - Barra lateral colapsada, navegação móvel, exibições de cabeçalho pequeno
- logoDark.png - Barra de cabeçalho principal (modo claro), cabeçalho do painel de administração
- logoLight.png - Telas de login/registro, fundos escuros, carrossel de autenticação
Substituindo Logos:
-
Crie Seus Arquivos de Logo:
- Use o formato PNG para suporte à transparência
- Correspondam às dimensões recomendadas acima
- Certifique-se de que os logos estejam claros em resoluções regulares e retina
-
Adicione ao OmniCRM:
# Copie seus arquivos de logo para o diretório de imagens omnitouch
cp /path/to/your/logoSm.png OmniCRM-UI/src/assets/images/omnitouch/
cp /path/to/your/logoDark.png OmniCRM-UI/src/assets/images/omnitouch/
cp /path/to/your/logoLight.png OmniCRM-UI/src/assets/images/omnitouch/ -
Reconstrua a UI:
cd OmniCRM-UI
npm run build -
Verifique as Alterações:
- Verifique o cabeçalho do modo claro (deve mostrar
logoDark.png) - Verifique o cabeçalho do modo escuro (deve mostrar
logoLight.png) - Verifique a barra lateral colapsada (deve mostrar
logoSm.png) - Verifique a tela de login (deve mostrar
logoLight.png)
- Verifique o cabeçalho do modo claro (deve mostrar
Melhores Práticas de Design de Logo:
- Contraste - Certifique-se de que os logos sejam visíveis em fundos claros e escuros
- Simplicidade - Logos devem ser reconhecíveis em tamanhos pequenos
- Formato - Use PNG com fundos transparentes
- Retina - Forneça resolução 2x para displays de alta DPI
- Consistência - Use as mesmas cores da marca em todas as variantes do logo
Telas de Splash e Fundos de Autenticação
As telas de autenticação (login, registro, redefinição de senha) usam um fundo de carrossel com imagens personalizáveis.
Localização:
/OmniCRM-UI/src/pages/AuthenticationInner/authCarousel.js
Configuração Padrão:
import logoLight from "../../assets/images/logo-light.png";
// Logo exibido nas telas de autenticação
<img src={logoLight} alt="" height="18" />
Personalizando Telas de Autenticação:
- Substitua
logo-light.pngem/OmniCRM-UI/src/assets/images/ - Adicione CSS de fundo personalizado à classe
.auth-one-bg - Modifique as citações do carrossel em
authCarousel.jspara corresponder à sua voz de marca
Exemplo de Personalização:
/* Adicione ao seu CSS personalizado */
.auth-one-bg {
background-image: url('/assets/images/custom-auth-bg.jpg');
background-size: cover;
background-position: center;
}
Arquivo de Configuração do CRM (crm_config.yaml)
O arquivo crm_config.yaml é a configuração central para a API do OmniCRM, controlando integrações, provisionamento, modelos de e-mail e serviços externos.
Localização: /OmniCRM/OmniCRM-API/crm_config.yaml
Configuração do Banco de Dados
database:
username: omnitouch
password: omnitouch2024
server: localhost
Nota: Isso deve corresponder às suas credenciais de banco de dados no arquivo .env. Em implantações em contêiner, o servidor é tipicamente db (nome do serviço Docker).
Tipos de Serviço
Defina tipos de serviço válidos para sua implantação:
service_types:
- omnicharge
- mobile
- fixed
- fixed-voice
- hotspot
- dongle
Esses são usados em todo o sistema para:
- Categorização de produtos
- Filtragem de addons (addons correspondem a tipos de serviço)
- Fluxos de trabalho de provisionamento
- Relatórios e análises
Integração HSS (Home Subscriber Server)
Para operadores de rede móvel com integração HSS:
hss:
hss_peers:
- 'http://10.179.2.140:8080'
apn_list: "1,2,3,4,5,6"
Configuração:
hss_peers- Lista de endpoints HSS para provisionamento de assinantesapn_list- Lista separada por vírgulas de IDs de APN disponíveis para provisionamento
Configuração do Modelo de E-mail Mailjet
O OmniCRM usa o Mailjet para e-mails transacionais. Cada tipo de e-mail tem sua própria configuração de modelo:
mailjet:
api_key: your_mailjet_api_key
api_secret: your_mailjet_api_secret
# E-mail de Boas-Vindas ao Cliente
api_crmCommunicationCustomerWelcome:
from_email: "support@yourcompany.com"
from_name: "Seu Suporte da Empresa"
template_id: 5977509
subject: "Bem-vindo à YourCompany"
# E-mail de Fatura ao Cliente
api_crmCommunicationCustomerInvoice:
from_email: "billing@yourcompany.com"
from_name: "Cobrança da Sua Empresa"
template_id: 6759851
subject: "Sua Fatura - "
# Lembrete de Fatura
api_crmCommunicationCustomerInvoiceReminder:
from_email: "billing@yourcompany.com"
from_name: "Cobrança da Sua Empresa"
template_id: 5977570
subject: "Lembrete de Pagamento de Fatura"
# E-mail de Boas-Vindas ao Usuário (Equipe/Admin)
api_crmCommunicationUserWelcome:
from_email: "admin@yourcompany.com"
from_name: "Admin da Sua Empresa"
template_id: 6118112
subject: "Bem-vindo à Equipe"
# Solicitação de Redefinição de Senha
api_crmCommunicationUserPasswordReset:
from_email: "security@yourcompany.com"
from_name: "Segurança da Sua Empresa"
template_id: 6735666
subject: "Solicitação de Redefinição de Senha"
# Confirmação de Sucesso na Redefinição de Senha
api_crmCommunicationUserPasswordResetSuccess:
from_email: "security@yourcompany.com"
from_name: "Segurança da Sua Empresa"
template_id: 6118378
subject: "Redefinição de Senha Bem-Sucedida"
# Notificação de Mudança de Senha
api_crmCommunicationUserPasswordChange:
from_email: "security@yourcompany.com"
from_name: "Segurança da Sua Empresa"
template_id: 6118423
subject: "Senha Alterada"
# Verificação de E-mail
api_crmCommunicationEmailVerification:
from_email: "verify@yourcompany.com"
from_name: "Verificação da Sua Empresa"
template_id: 6267350
subject: "Verifique Seu Endereço de E-mail"
# Notificação de Saldo Expirado
api_crmCommunicationsBalanceExpired:
from_email: "alerts@yourcompany.com"
from_name: "Alertas da Sua Empresa"
template_id: 7238252
subject: "Saldo de Serviço Expirado"
# Aviso de Saldo Baixo
api_crmCommunicationsBalanceLow:
from_email: "alerts@yourcompany.com"
from_name: "Alertas da Sua Empresa"
template_id: 7238263
subject: "Aviso de Saldo Baixo"
Criando Modelos Mailjet:
- Faça login no painel do Mailjet (<https://app.mailjet.com>)
- Navegue até Transacional → Modelos
- Crie um novo modelo ou clone um existente
- Anote o ID do Modelo (valor numérico)
- Adicione variáveis de modelo correspondentes à estrutura de dados do OmniCRM
- Atualize
crm_config.yamlcom o ID do modelo
Variáveis de Modelo Disponíveis:
Cada tipo de e-mail recebe variáveis específicas. Exemplos comuns:
{{customer_name}}- Nome do cliente ou usuário{{service_name}}- Nome do serviço ou produto{{invoice_id}}- Número da fatura{{invoice_amount}}- Valor total da fatura{{due_date}}- Data de vencimento do pagamento{{reset_link}}- URL de redefinição de senha{{verification_link}}- URL de verificação de e-mail{{balance}}- Saldo atual da conta{{expiry_date}}- Data de expiração do saldo ou serviço
Configuração de Provisionamento
provisioning:
failure_list: ['admin@yourcompany.com', 'ops@yourcompany.com']
Propósito:
failure_list- Endereços de e-mail notificados quando o provisionamento do Ansible falha- As notificações incluem o nome do playbook, detalhes do erro e informações do cliente
- Permite que a equipe de operações responda rapidamente a problemas de provisionamento
Configuração de Fatura
invoice:
template_filename: 'yourcompany_invoice_template.html'
Propósito:
Especifica qual modelo HTML Jinja2 usar para a geração de faturas em PDF.
Localização do Modelo: /OmniCRM-API/invoice_templates/
Veja a seção Geração de PDF de Fatura abaixo para detalhes sobre como criar modelos personalizados.
URL Base do CRM
crm:
base_url: 'http://localhost:5000'
Propósito:
- Usado por playbooks do Ansible para fazer chamadas de API
- Usado em modelos de e-mail para gerar links para o CRM
- Deve ser a URL publicamente acessível da sua API (não nomes de contêiner internos)
Exemplos:
- Desenvolvimento:
http://localhost:5000 - Produção:
https://api.yourcompany.com - Docker:
http://omnicrm-api:5000(comunicação interna entre contêineres)
Configuração do OCS e CGRates
ocs:
ocsApi: 'http://10.179.2.142:8080/api'
ocsTenant: 'mnc380.mcc313.3gppnetwork.org'
cgrates: 'localhost:2080'
Configuração:
ocsApi- Endpoint da API OCS para gerenciamento de assinantesocsTenant- Identificador do inquilino para implantações OCS multi-inquilinocgrates- Endpoint da API JSON-RPC do CGRates (host:port)
Configuração do SMSC (Gateway SMS)
smsc:
source_msisdn: 'YourCompany'
smsc_url: 'http://10.179.2.216/SMSc/'
api_key: 'your_smsc_api_key'
Propósito:
- Enviar notificações SMS para clientes (saldo baixo, alertas de serviço, códigos 2FA)
source_msisdn- ID do remetente exibido para os destinatários (alfanumérico ou número de telefone)smsc_url- Endpoint da API do gateway SMSCapi_key- Autenticação para a API do SMSC
Chave Secreta JWT
jwt_secret: '2b93110f723db60172c8e9a1eaa80027a9a9c3f05b44e50dc3fcf38dba68d87e'
Segurança:
- Usado para assinar e verificar tokens de autenticação
- DEVE ser alterado do valor padrão em produção
- Gere uma string aleatória segura (mínimo 64 caracteres)
- Nunca compartilhe ou comite no controle de versão
Gerando uma Nova Chave Secreta JWT:
# Gere uma chave aleatória criptograficamente segura
python3 -c "import secrets; print(secrets.token_hex(32))"
Configuração de Pagamento Stripe
stripe:
secret_key: 'sk_live_xxxxxxxxxx'
publishable_key: 'pk_live_xxxxxxxxxx'
currency: 'aud'
statement_descriptor_suffix: 'YOURCOMPANY'
Configuração:
secret_key- Chave secreta da API Stripe (lado do servidor, mantenha confidencial)publishable_key- Chave publicável da Stripe (lado do cliente, seguro para expor)currency- Código de moeda ISO 4217 (aud, usd, gbp, eur, etc.)statement_descriptor_suffix- Aparece nos extratos de cartão de crédito dos clientes
Uso do Descritor de Extrato:
- Exibido nos extratos bancários dos clientes como "YOURCOMPANY"
- Máximo de 22 caracteres
- Ajuda os clientes a identificar cobranças
- Também usado nos nomes de arquivos PDF de fatura (por exemplo,
YOURCOMPANY_12345.pdf)
Chaves da API e Listagem de IPs
Defina chaves da API com acesso baseado em funções e restrições de IP:
api_keys:
"YOUR_API_KEY_1":
roles: ["admin"]
ips: ["127.0.0.1", "::1"]
"YOUR_API_KEY_2":
roles: ["customer_service_agent_1"]
ips: ["127.0.0.1", "::1", "10.0.1.0/24"]
# Lista Branca de IP (autônoma, sem chave da API)
ip_whitelist:
"10.179.2.142":
roles: ["admin"]
Propósito:
- Permitir que sistemas externos se autentiquem via chave da API
- Restringir acesso por endereço IP
- Conceder funções específicas aos consumidores da API
- Útil para integrações (sistemas de faturamento, monitoramento, automação)
Melhores Práticas de Segurança:
- Use chaves da API longas e aleatórias (mínimo 32 caracteres)
- Restringir IPs apenas a fontes conhecidas
- Conceder as funções mínimas necessárias
- Rotacione chaves da API regularmente
- Monitore o uso da chave da API nos logs
Geração de PDF de Fatura
O OmniCRM gera faturas PDF profissionais usando modelos HTML Jinja2 e renderização de PDF WeasyPrint.
Como Funciona a Geração de PDF
- Seleção do Modelo:
- O nome do arquivo do modelo é especificado em
crm_config.yamlsobinvoice.template_filename - O modelo é carregado do diretório
/OmniCRM-API/invoice_templates/
- O nome do arquivo do modelo é especificado em
- Preparação de Dados:
- Os dados da fatura (ID, datas, valores, status) são buscados no banco de dados
- As informações do cliente (nome, endereço) são recuperadas
- A lista de transações é compilada (todas as cobranças/créditos na fatura)
- Renderização do Modelo:
- Jinja2 renderiza o modelo HTML com os dados da fatura
- Variáveis como
{{ invoice_number }},{{ total_amount }}, etc. são substituídas - O HTML renderizado é salvo em
invoice_templates/rendered/para depuração
- Geração do PDF:
- WeasyPrint converte o HTML renderizado em PDF
- O PDF suporta estilização CSS, imagens, quebras de página, cabeçalhos/rodapés
- Os dados binários do PDF são gerados na memória
- Cache:
- O PDF é codificado em Base64 e armazenado na tabela
Invoice_PDF_Cache - Um hash SHA256 é calculado para verificação de integridade
- Solicitações subsequentes retornam o PDF em cache (entrega instantânea)
- O PDF é codificado em Base64 e armazenado na tabela
- Invalidação do Cache:
- O cache é invalidado quando a fatura é modificada, anulada ou reembolsada
- Alterações no modelo não invalidam automaticamente caches existentes
Estrutura do Modelo de Fatura
Os modelos de fatura são arquivos HTML Jinja2 com variáveis e lógica incorporadas.
Localização do Modelo:
/OmniCRM-API/invoice_templates/yourcompany_invoice_template.html
Variáveis Disponíveis:
{
'invoice_number': 12345,
'date': '2025-01-04',
'client': {
'name': 'John Smith',
'address': {
'address_line_1': '123 Main St',
'city': 'Sydney',
'state': 'NSW',
'zip_code': '2000',
'country': 'Australia'
}
},
'transaction_list': [
[
{
'transaction_id': 1,
'title': 'Serviço Móvel - Taxa Mensal',
'retail_cost': 30.00,
'wholesale_cost': 10.00,
'created': '2025-01-01'
},
{
'transaction_id': 2,
'title': 'Addon de Dados - 5GB',
'retail_cost': 15.00,
'wholesale_cost': 5.00,
'created': '2025-01-15'
}
]
],
'total_amount': 45.00,
'due_date': '2025-01-31',
'start_date': '2025-01-01',
'end_date': '2025-01-31',
'paid': False,
'void': False
}
Exemplo de Trecho de Modelo:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Fatura {{ invoice_number }}</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.invoice-details {
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
th {
background-color: #405189;
color: white;
}
.total {
text-align: right;
font-size: 18px;
font-weight: bold;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="header">
<img src="file:///path/to/logo.png" alt="Logo da Empresa" height="60">
<h1>FATURA</h1>
</div>
<div class="invoice-details">
<p><strong>Número da Fatura:</strong> {{ invoice_number }}</p>
<p><strong>Data:</strong> {{ date }}</p>
<p><strong>Data de Vencimento:</strong> {{ due_date }}</p>
<p><strong>Período de Cobrança:</strong> {{ start_date }} a {{ end_date }}</p>
</div>
<div class="customer-details">
<h3>Faturar Para:</h3>
<p>{{ client.name }}</p>
<p>{{ client.address.address_line_1 }}</p>
<p>{{ client.address.city }}, {{ client.address.state }} {{ client.address.zip_code }}</p>
<p>{{ client.address.country }}</p>
</div>
<table>
<thead>
<tr>
<th>Descrição</th>
<th>Data</th>
<th>Valor</th>
</tr>
</thead>
<tbody>
{% for transaction in transaction_list[0] %}
<tr>
<td>{{ transaction.title }}</td>
<td>{{ transaction.created }}</td>
<td>${{ "%.2f"|format(transaction.retail_cost) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="total">
<p>Valor Total Devido: ${{ "%.2f"|format(total_amount) }}</p>
</div>
{% if paid %}
<div style="text-align: center; color: green; font-weight: bold;">
PAGO
</div>
{% endif %}
{% if void %}
<div style="text-align: center; color: red; font-weight: bold;">
ANULADO
</div>
{% endif %}
</body>
</html>
Melhores Práticas para Modelos:
- Use caminhos absolutos para imagens -
file:///absolute/path/to/image.png - CSS Inline - O WeasyPrint não carrega folhas de estilo externas de forma confiável
- Teste com dados de exemplo - Use
invoice_templates/rendered/para inspecionar HTML - Quebras de página - Use
<div style="page-break-after: always;"></div>para faturas de várias páginas - Cabeçalhos e rodapés - Use regras CSS
@pagepara elementos repetidos - Formatação de moeda - Use filtros Jinja2:
{{ "%.2f"|format(amount) }}
Criando um Modelo de Fatura Personalizado
-
Copie o Modelo de Exemplo:
cd /OmniCRM/OmniCRM-API/invoice_templates
cp norfone_invoice_template.html yourcompany_invoice_template.html -
Edite o Modelo:
- Substitua o nome da empresa, logo, informações de contato
- Ajuste o estilo (cores, fontes, layout) para corresponder à marca
- Adicione ou remova seções conforme necessário (quebra de impostos, instruções de pagamento, etc.)
-
Atualize a Configuração:
Edite
crm_config.yaml:invoice:
template_filename: 'yourcompany_invoice_template.html' -
Teste a Geração de Faturas:
- Crie uma fatura de teste no CRM
- Baixe o PDF e verifique a formatação
- Verifique
invoice_templates/rendered/{invoice_id}.htmlpara depuração
-
Invalidate Caches Antigos (se necessário):
Se você alterou o modelo e deseja regenerar faturas existentes:
-- Limpar todos os PDFs em cache (força a regeneração)
DELETE FROM Invoice_PDF_Cache;
Sistema de Cache de PDF
Para melhorar o desempenho, o OmniCRM armazena em cache PDFs gerados:
Comportamento do Cache:
- Primeira Solicitação - O PDF é gerado, armazenado em cache e retornado
- Solicitações Subsequentes - O PDF em cache é retornado imediatamente (sem regeneração)
- Invalidação do Cache - Ocorre quando a fatura é modificada, anulada ou reembolsada
- Limpeza do Cache - Caches antigos são automaticamente removidos após 30 dias de inatividade
Armazenamento do Cache:
- PDF codificado em Base64 armazenado na tabela
Invoice_PDF_Cache - Hash SHA256 do conteúdo para verificação de integridade
- Inclui nome do arquivo, timestamp de criação, timestamp do último acesso
Gerenciamento Manual do Cache:
# Na API do OmniCRM ou shell Python
from services.invoice_service import cleanup_old_pdf_cache, invalidate_invoice_cache
from utils.db_helpers import get_db_session
session = get_db_session()
# Limpar caches mais antigos que 30 dias
result = cleanup_old_pdf_cache(session, days_old=30)
print(result) # {'status': 'success', 'deleted_count': 15}
# Invalidar cache de fatura específica
invalidate_invoice_cache(session, invoice_id='12345')
Endpoints da API:
Gerar/download PDF de fatura:
GET /invoice/pdf/{invoice_id}
Resposta: Download do arquivo PDF com nome do descritor de extrato do Stripe
Cabeçalhos de Cache:
- Primeira solicitação: Resposta mais lenta (tempo de geração)
- Solicitações em cache: Resposta instantânea
- Acerto/falha de cache é transparente para o usuário
Resolução de Problemas
Geração de PDF Falha:
- Verifique se o WeasyPrint está instalado:
pip install weasyprint - Verifique se o nome do modelo corresponde ao
crm_config.yaml - Verifique
invoice_templates/rendered/para erros de renderização HTML - Revise os logs da API para erros de modelo Jinja2
Imagens Não Aparecendo no PDF:
- Use caminhos de arquivo absolutos:
file:///full/path/to/image.png - Certifique-se de que os arquivos de imagem existam e sejam legíveis
- Verifique o formato da imagem (PNG e JPEG funcionam melhor)
- Verifique se os caminhos das imagens não contêm caracteres especiais
Problemas de Estilo:
- Inline todos os CSS (folhas de estilo externas não são suportadas)
- Evite recursos CSS complexos (flexbox, grid podem não renderizar corretamente)
- Teste com layouts simples primeiro, adicione complexidade gradualmente
- Use tabelas para layout em vez de divs sempre que possível
Cache Não Invalida:
- Verifique se
invalidate_invoice_cache()é chamado quando a fatura é modificada - Verifique se as atualizações de transações acionam a invalidação do cache
- Exclua manualmente da tabela
Invoice_PDF_Cachese necessário
Lista de Verificação de Configuração
Use esta lista de verificação ao implantar o OmniCRM:
Configuração de Backend
- [ ] Copie
.env.examplepara.env - [ ] Defina senhas fortes para o banco de dados
- [ ] Configure credenciais do CGRates
- [ ] Atualize
crm_config.yamlcom suas configurações:- [ ] Conexão com o banco de dados
- [ ] Tipos de serviço
- [ ] Chaves da API do Mailjet e IDs de modelo
- [ ] E-mails de notificação de falha de provisionamento
- [ ] Nome do arquivo do modelo de fatura
- [ ] URL base do CRM (acessível publicamente)
- [ ] Endpoints OCS/CGRates
- [ ] Configuração do SMSC
- [ ] Gere nova chave secreta JWT
- [ ] Chaves do Stripe (ao vivo, não teste)
- [ ] Chaves da API e listagem de IPs
Configuração de Frontend
- [ ] Copie
OmniCRM-UI/.env.exampleparaOmniCRM-UI/.env - [ ] Defina a chave da API do Google Maps
- [ ] Defina a chave publicável do Stripe
- [ ] Atualize a marca da empresa:
- [ ] Nome da empresa
- [ ] Nome do portal
- [ ] Nome do autoatendimento
- [ ] Slogan da empresa
- [ ] Configure a localização:
- [ ] Idioma padrão
- [ ] Localidade
- [ ] Localização e país padrão
- [ ] Código e símbolo da moeda
- [ ] Defina a cor primária da marca
- [ ] Configure integrações de aplicativos web (opcional)
- [ ] Adicione URLs de suporte e FAQ (opcional)
Ativos de Marca
- [ ] Crie arquivos de logo (logoSm.png, logoDark.png, logoLight.png)
- [ ] Faça upload dos logos para
OmniCRM-UI/src/assets/images/omnitouch/ - [ ] Crie HTML de modelo de fatura personalizado
- [ ] Faça upload do modelo de fatura para
OmniCRM-API/invoice_templates/ - [ ] Atualize
crm_config.yamlcom o nome do arquivo do modelo de fatura - [ ] Teste a geração de PDF de fatura
- [ ] Reconstrua a UI:
npm run build
Segurança
- [ ] Altere todas as senhas padrão
- [ ] Gere um JWT secreto exclusivo
- [ ] Use chaves do Stripe em produção (não chaves de teste)
- [ ] Rotacione chaves da API do Mailjet
- [ ] Habilite regras de firewall
- [ ] Configure listagem de IPs para acesso à API
- [ ] Configure certificados SSL/TLS
- [ ] Habilite HTTPS para todos os endpoints
- [ ] Revise configurações de CORS
- [ ] Implemente limitação de taxa
- [ ] Configure procedimentos de backup e recuperação
Testes
- [ ] Teste o fluxo de registro de cliente
- [ ] Teste o provisionamento de serviço de ponta a ponta
- [ ] Verifique se as notificações por e-mail são enviadas corretamente
- [ ] Teste a geração de faturas e download de PDF
- [ ] Verifique o processamento de pagamentos (Stripe)
- [ ] Verifique a autenticação de usuários e 2FA
- [ ] Teste a impessoalização e o registro de auditoria
- [ ] Verifique se os dados de uso são sincronizados do OCS
- [ ] Teste a criação e renovação de ActionPlan
- [ ] Confirme se a alocação de inventário funciona corretamente
Implantação
- [ ] Construa imagens Docker ou implante em servidores
- [ ] Inicie contêineres de banco de dados (MySQL, PostgreSQL)
- [ ] Inicie o CGRates
- [ ] Inicie a API do OmniCRM
- [ ] Inicie a UI do OmniCRM
- [ ] Configure o proxy reverso (nginx, traefik)
- [ ] Configure monitoramento (Grafana, Prometheus)
- [ ] Configure agregação de logs
- [ ] Configure backups automáticos
- [ ] Documente a arquitetura de implantação
- [ ] Treine a equipe sobre o uso do sistema