# 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 ```bash # 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: ```json { "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): ```json { "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).*