Pular para o conteúdo principal

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.example como 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 clientes
  • PORTAL_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.

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:

  1. 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
  2. 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/
  3. Reconstrua a UI:

    cd OmniCRM-UI
    npm run build
  4. 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)

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:

  1. Substitua logo-light.png em /OmniCRM-UI/src/assets/images/
  2. Adicione CSS de fundo personalizado à classe .auth-one-bg
  3. Modifique as citações do carrossel em authCarousel.js para 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 assinantes
  • apn_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:

  1. Faça login no painel do Mailjet (<https://app.mailjet.com>)
  2. Navegue até TransacionalModelos
  3. Crie um novo modelo ou clone um existente
  4. Anote o ID do Modelo (valor numérico)
  5. Adicione variáveis de modelo correspondentes à estrutura de dados do OmniCRM
  6. Atualize crm_config.yaml com 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 assinantes
  • ocsTenant - Identificador do inquilino para implantações OCS multi-inquilino
  • cgrates - 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 SMSC
  • api_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

  1. Seleção do Modelo:
    • O nome do arquivo do modelo é especificado em crm_config.yaml sob invoice.template_filename
    • O modelo é carregado do diretório /OmniCRM-API/invoice_templates/
  2. 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)
  3. 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
  4. 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
  5. 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)
  6. 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 @page para elementos repetidos
  • Formatação de moeda - Use filtros Jinja2: {{ "%.2f"|format(amount) }}

Criando um Modelo de Fatura Personalizado

  1. Copie o Modelo de Exemplo:

    cd /OmniCRM/OmniCRM-API/invoice_templates
    cp norfone_invoice_template.html yourcompany_invoice_template.html
  2. 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.)
  3. Atualize a Configuração:

    Edite crm_config.yaml:

    invoice:
    template_filename: 'yourcompany_invoice_template.html'
  4. 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}.html para depuração
  5. 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_Cache se 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.example para .env
  • [ ] Defina senhas fortes para o banco de dados
  • [ ] Configure credenciais do CGRates
  • [ ] Atualize crm_config.yaml com 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.example para OmniCRM-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.yaml com 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

Documentação Relacionada