servico_plugnotas_teste/README.md
2026-07-10 16:32:22 -03:00

12 KiB

Serviço de Integração PlugNotas da Tecnospeed

Serviço especializado e containerizado para gerenciar a emissão, controle e recebimento de informações sobre Notas Fiscais (NFe e NFSe) via API da PlugNotas (Tecnospeed). Com uma arquitetura orientada a eventos e filas (RabbitMQ), o sistema é altamente desacoplado, assíncrono e integrado a um banco de dados PostgreSQL para registro de todas as operações e relatórios de auditoria.

🚀 Principais Tecnologias e Arquitetura

  • Python & FastAPI: Base de processamento, recebimento de Webhooks (via main_listener.py) e tipagem rigorosa utilizando Pydantic.
  • RabbitMQ (AMQP): Comunicação entre os módulos utilizando as ferramentas especializadas implementadas (como QueueExchange2 e RPCExchange2), promovendo uma arquitetura event-driven livre de bloqueios síncronos.
  • PostgreSQL: Utilizado com SQLAlchemy para logs, auditorias detalhadas das operações, cache das bases de Serviços, Tomadores, Empresas e relatórios operacionais.
  • Redis: Sistema de gerenciamento e armazenamento de persistência de curadoria (como configurações dinâmicas de acesso e credenciais de forma ágil).
  • IC2 Logger: Envio centralizado de todos os logs, fluxos de erros, métricas operacionais para um sistema InfoConnector usando RabbitMQ Topic.

📦 Estrutura de Módulos (Serviços)

O serviço central funciona consumindo a fila tecnospeed e encaminhando as requisições para os seus respectivos módulos especializados.

1. NFe (Nota Fiscal Eletrônica de Produto)

Módulo que envia e orquestra operações envolvendo notas fiscais de venda (produtos):

  • Envio de emissões de NFe em unitário ou em lote.
  • Consulta de resumos processados.
  • Cancelamentos suportados por justificativas.
  • Envio de Cartas de Correção Eletrônica (CCe).
  • Download de relatórios, XMLs originais e PDFs de Danfe.

2. NFSe (Nota Fiscal de Serviços Eletrônica)

Voltado a comunicações com prefeituras para emissão de serviços, contém os fluxos de controle essenciais:

  • Realiza emissão dos documentos pelo CNPJ do prestador.
  • Controle e solicitação formal de cancelamento nas prefeituras.
  • Verificação de status e download de histórico de RPS.
  • Tomadores: Gerenciamento integrado dos clientes finais (Tomadores da NFSe).
  • Serviços: Cadastro de descritivos padrão, itens e alíquotas com base na lei complementar municipal local (LC116).

3. Empresas e Certificados Digitais

Serviço de onboarding das novas contas emissoras junto à PlugNotas:

  • Empresas: Vinculação do CNPJ emissor (incluindo endereços, configurações fiscais iniciais e logotipos de impressão).
  • Certificados Digitais: Responsável pelo cadastro do certificado físico formato .pfx com envios do tipo multipart/form-data, renovação de senhas e update recorrente dos certificados A1.

4. Webhooks (Listeners Internos e Externos)

Gerenciador automatizado orientando o lado da PlugNotas para onde devolver as informações assincronamente:

  • Criação, leitura, deleção e envio de testes para registro das URLs via API do Plugnotas.
  • Um Listener próprio do lado da integração (main_listener.py + listenerEndpoint.py) absorve o payload recebido da PlugNotas e encaminha de volta ao fluxo RabbitMQ principal usando RPC — mantendo assim uma auditoria segura com log para todas as frentes (rejeições, aceites contábeis etc).

5. Relatórios

Serviço voltado a buscas gerenciais dentro do portal da Tecnospeed para contabilidades e analistas de sistemas:

  • Extratos iterados limitados de NFe e NFSe emitidas ou registradas num dado range de período.
  • Recortes centralizados e consolidações por um CNPJ específico.

⚙️ Como Funciona o Ciclo de Eventos (Workflows)

  1. Ação Disparada: O sistema que integra de fora (ERP etc) publica uma mensagem JSON na fila RabbitMQ com os comandos e a carga de dados de Pydantic Models associada, incluindo as configurações do banco.
  2. Workers de Fila (mainQUEUE.py): As mensagens são absorvidas, descriptografadas, instanciam as credenciais adequadas e ativam a Controller/Service (ex: EmpresaController, RegistroNFeService).
  3. Persistência no Postgre (utils/banco.py): A operação feita junto as rotas do portal salva um rastro de log com o status ("SUCESSO", "ERRO"). Instalações da NFe e NFSe e Certificados refletem diretamente nesse PostgreSQL.
  4. Listener Asincrono de Retorno (listenerEndpoint.py): A rota em FastAPI escuta atualizações atrasadas (ex: webservices estaduais demorados) e sinaliza ativamente ao logger e à base da empresa o desfecho da nota.

🗂️ Estrutura de Diretórios

servico_plugnotas/
├── src/
│   ├── main.py                    # Worker principal (RPCExchange2)
│   ├── mainQUEUE.py               # Worker alternativo (QueueExchange2 + IC2 Logger)
│   ├── main_listener.py           # Entrypoint do container de Webhook Listener
│   ├── listenerEndpoint.py        # Rotas FastAPI que recebem webhooks da PlugNotas
│   ├── test.py                    # Script de testes manuais
│   │
│   ├── NFe/
│   │   └── registroNFe.py         # Service de emissão, cancelamento e download de NFe
│   ├── NFSe/
│   │   ├── nfse.py                # Service de emissão e controle de NFSe
│   │   ├── Servico/
│   │   │   └── servico.py         # Controller de cadastro de Serviços (LC116)
│   │   └── Tomador/
│   │       └── tomador.py         # Controller de cadastro de Tomadores
│   ├── empresas/
│   │   └── empresa.py             # Controller de cadastro de Empresas emissoras
│   ├── certificado_digital/
│   │   └── certificado_digital.py # Service de upload e gestão de certificados .pfx
│   ├── webhooks/
│   │   └── webhooks.py            # CRUD de URLs de webhook por CNPJ
│   ├── Relatorios/
│   │   └── relatorios.py          # Consultas de relatórios em lote
│   │
│   ├── Models/                    # Modelos Pydantic que validam os payloads
│   │   ├── config.py              # Config (banco) e SystemConfig (AMQP/Redis)
│   │   ├── empresa.py             # Modelo de Empresa emissora
│   │   ├── nfe.py                 # Modelo de NFe (Emitente, Destinatário, Itens, Tributos)
│   │   ├── nfse.py                # Modelo de NFSe (Prestador, Tomador, Serviço)
│   │   ├── servico.py             # Modelo detalhado de Serviço (ISS, Retenções, IBPT)
│   │   └── tomador.py             # Modelo de Tomador (cliente fiscal)
│   │
│   └── utils/                     # Classes auxiliares compartilhadas
│       ├── api.py                 # Wrapper HTTP (requests) para a API PlugNotas
│       ├── banco.py               # ORM SQLAlchemy (tabelas + CRUD + logs)
│       ├── redis.py               # Cliente Redis para cache de configurações
│       ├── Exchange2.py           # QueueExchange2, RPCExchange2, LoggerExchange2
│       ├── exchangeModels.py      # Modelos Pydantic do InfoConnector (IC2)
│       └── Logger.py              # LogService para logs via mensageria
│
├── Dockerfile                     # Imagem base Python 3.12-slim
├── docker-compose.yml             # Orquestração dos containers
├── buildImages.sh                 # Script de build com clone de dependências
├── requirements.txt               # Dependências Python
├── modelo_system_config.json      # Exemplo de configuração do Redis
└── modelo_json_rpc.json           # Exemplo de payload RPC

🐳 Infraestrutura Docker

O projeto é composto por 4 containers orquestrados via docker-compose.yml:

Container Imagem Porta Função
redis redis interna Armazena system_config (credenciais AMQP, chaves)
postgres postgres:15 interna Banco de dados de auditoria e registros de notas
tecnospeed build local Worker que consome fila RabbitMQ e processa operações
webhook-listener build local 8000 FastAPI que recebe webhooks da PlugNotas via HTTP

Subindo o ambiente

# Build e execução completa
docker compose up -d --build

# Ou utilizando o script de build (clona dependências externas automaticamente)
bash buildImages.sh clone

Variáveis de ambiente

Variável Container Descrição Default
TZ todos Timezone da aplicação America/Sao_Paulo
REDIS_HOST tecnospeed, webhook-listener Host do Redis localhost
WEBHOOK_PORT webhook-listener Porta do servidor FastAPI 8000

Configuração Inicial (Redis)

Antes de subir os workers, é necessário inserir a chave system_config no Redis com as credenciais de acesso ao RabbitMQ:

{
    "serviceid": "01234567890123456789012345678901",
    "servicekey": "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456",
    "origin": "nome-da-maquina",
    "amqps": "amqps://usuario:senha@host.rmq.cloudamqp.com/vhost"
}

Esse JSON é lido automaticamente na inicialização dos workers (main.py, mainQUEUE.py, listenerEndpoint.py).

📨 Exemplo de Payload RPC

As mensagens que chegam pela fila RabbitMQ seguem o seguinte formato (já descriptografado):

{
    "fila": "nfse",
    "cliente": "NomeCliente",
    "metodo": "POST",
    "dados": { ... },
    "config": {
        "api_key": "sua-api-key-plugnotas",
        "user_postgres": "postgres",
        "pass_postgres": "postgres",
        "host_postgres": "localhost",
        "port_postgres": "5432",
        "database_postgres": "tecnospeed"
    }
}
  • fila: Seleciona o módulo de destino (nfe, nfse, empresa, certificado_digital, servico, tomador, webhooks, relatorios, webhook_callback).
  • metodo: Ação a executar (post, get, put, delete, cancelar, download, etc.).
  • dados: Corpo da requisição conforme o Pydantic Model do módulo.
  • config: Credenciais isoladas por cliente para a API e o banco PostgreSQL.

📦 Dependências

sqlalchemy          # ORM para PostgreSQL
pydantic            # Validação de modelos de dados
requests            # Requisições HTTP à API PlugNotas
redis               # Cliente Redis
pytz                # Timezone São Paulo
pika                # Cliente AMQP (RabbitMQ)
cryptography        # Criptografia AES-256 dos payloads
psycopg2-binary     # Driver PostgreSQL
fastapi             # Framework HTTP para o Webhook Listener
uvicorn[standard]   # Servidor ASGI

🔖 Versionamento

Versão Descrição
1.0.0 Versão inicial do sistema
1.0.1 Implementação do ORM (SQLAlchemy)
1.0.2 Implementação de RPC via RabbitMQ
1.0.3 Configuração dinâmica via Redis
2.0.0 Suporte a NFe e refatoração da Main
2.0.1 Refatoração para RPCExchange2 / QueueExchange2

Documento gerado com base no código operacional contido em src/ do serviço (v2.0.1).