# ⚡ QUICK REFERENCE - Sistema de Importação NFe

## 🚀 TL;DR (Muito Longo; Não Li)

Importar XML de NFe → Armazenar em banco de dados → Validar e vincular à viagem

---

## 📂 Arquivos Principais

```
/include/xml_parsers/
  └─ nfe_parser.php .................. Parser que extrai dados do XML (600 linhas)

/tms010_operacao/
  ├─ import_xml.php .................. Endpoint que recebe XML e armazena no banco ✨
  ├─ funcoes_importacao_nf.php ....... 4 funções para inserir/buscar dados ✨
  ├─ cad.php ......................... Formulário principal (adicionar modal + JS)
  └─ teste_xml.php ................... Página de teste do parser

/
  ├─ MODELO_BANCO_DADOS.sql .......... Script SQL com 5 tabelas (400+ linhas) 📊
  ├─ MODELO_BANCO_DADOS_EXPLICADO.md  Documentação das tabelas (500+ linhas) 📖
  ├─ IMPLEMENTACAO_ARMAZENAMENTO_NF.md Fluxo de armazenamento (400+ linhas)
  ├─ TELA_VALIDACAO_NF.md ............ Design de modal + endpoints AJAX (500+ linhas)
  └─ STATUS_COMPLETO.md ............. Este documento resumido
```

---

## 🔧 Stack Técnico

| Componente | Tecnologia | Arquivo |
|-----------|-----------|---------|
| **XML Parser** | PHP 7.4+ | `nfe_parser.php` |
| **Banco** | PostgreSQL | `MODELO_BANCO_DADOS.sql` |
| **Frontend** | Bootstrap 5 + JS | `cad.php` + modal |
| **Icons** | Material Icons | `tms010.css` |
| **Autenticação** | Session PHP | `$_SESSION['id']` |

---

## 📊 Tabelas do Banco

### 1. `tms001_notafiscal` (Principal)
- PK: `(id, empresa)`
- UNIQUE: `chave_acesso`
- 40+ campos: ID, datas, clientes, valores, localização, status

### 2. `tms001_notafiscal_itens` (Detalhe)
- 1:N com notafiscal
- Um registro por item da nota

### 3. `tms001_nf_viagem` (N:M)
- Associa NFs a viagens
- Suporta múltiplas NFs por viagem
- UNIQUE: `(id_notafiscal, id_viagem)`

### 4. `tms001_nf_importacao` (Auditoria)
- UNIQUE: `hash_arquivo` (previne duplicatas)
- Status: sucesso | erro_xml | erro_validacao | duplicada

### 5. `tms001_cliente_temporario` (Clientes não encontrados)
- Status: 0=Pendente | 1=Confirmado | 2=Integrado
- Aguarda aprovação para integrar em `dim_cliente`

---

## 🔄 Fluxo de Dados

```
XML File
   ↓
[import_xml.php - validar, hash]
   ↓
[NFeLimpaParser - extrair dados]
   ↓
[buscar_ou_criar_cliente() - emitente]
   ↓
[buscar_ou_criar_cliente() - destinatário]
   ↓
[inserir_notafiscal() - INSERT principal]
   ↓
[inserir_itens_notafiscal() - INSERT itens]
   ↓
[registrar_importacao() - INSERT auditoria]
   ↓
JSON { id_notafiscal, dados }
   ↓
[Modal de validação - JavaScript]
   ↓
Usuário aprova clientes e vincula a viagem
```

---

## 📝 Funções Principais

### 1. `buscar_ou_criar_cliente()`
**O que faz:** Busca CNPJ em `dim_cliente`, cria em `tms001_cliente_temporario` se não encontrar

**Parâmetros:**
```php
$bdcon           // Conexão PostgreSQL
$empresa         // ID da empresa
$cnpj_cpf        // CNPJ ou CPF
$razao_social    // Nome
$tipo            // 'emitente' ou 'destinatario'
$dados_nfe       // Array do XML (contexto)
```

**Retorna:**
- `int` (idcliente) se encontrou em dim_cliente
- `null` se criou em temporário

### 2. `inserir_notafiscal()`
**O que faz:** INSERT em `tms001_notafiscal`

**Parâmetros:**
```php
$bdcon           // Conexão PostgreSQL
$empresa         // ID da empresa
$id_emitente     // De buscar_ou_criar_cliente()
$id_destinatario // De buscar_ou_criar_cliente()
$dados_nfe       // Array completo do parser
$idusuario       // De $_SESSION['id']
```

**Retorna:** ID da NF inserida (usado como FK nos itens)

### 3. `inserir_itens_notafiscal()`
**O que faz:** INSERT em `tms001_notafiscal_itens` (loop)

**Parâmetros:**
```php
$bdcon           // Conexão PostgreSQL
$id_notafiscal   // De inserir_notafiscal()
$itens           // Array de itens do $dados_nfe
```

**Retorna:** void (lança Exception se erro)

### 4. `registrar_importacao()`
**O que faz:** INSERT em `tms001_nf_importacao` (auditoria)

**Parâmetros:**
```php
$bdcon           // Conexão PostgreSQL
$empresa         // ID da empresa
$idusuario       // De $_SESSION['id']
$nome_arquivo    // Do $_FILES
$tamanho_arquivo // Do $_FILES
$hash_arquivo    // SHA256 do conteúdo
$status          // 'sucesso' | 'erro_xml' | 'erro_validacao' | 'duplicada'
$mensagem_erro   // Texto da mensagem
$id_notafiscal   // NULL se erro, ID da NF se sucesso
```

**Retorna:** void

---

## ✅ Testes Rápidos

### 1. Verificar se tabelas foram criadas
```sql
SELECT tablename FROM pg_tables 
WHERE schemaname = 'public' 
AND tablename LIKE 'tms001%';
```

### 2. Testar upload de XML
```bash
curl -X POST \
  -F "arquivo=@exemplos_xml/exemplo_nfe_completa.xml" \
  http://localhost/tms010_operacao/import_xml.php
```

### 3. Verificar dados inseridos
```sql
-- NFs
SELECT id, numero_nf, valor_total, status 
FROM tms001_notafiscal 
ORDER BY data_criacao DESC;

-- Itens
SELECT * FROM tms001_notafiscal_itens 
WHERE id_notafiscal = 1;

-- Clientes temporários
SELECT * FROM tms001_cliente_temporario 
WHERE status = 0;

-- Auditoria
SELECT * FROM tms001_nf_importacao 
ORDER BY data_importacao DESC;
```

---

## 🎯 Status de Cada Componente

| Componente | Status | O que fazer |
|-----------|--------|-----------|
| XML Parser | ✅ Pronto | Já está funcionando em teste_xml.php |
| Storage (BD) | ✅ Código pronto | Executar MODELO_BANCO_DADOS.sql e testar import_xml.php |
| Frontend Modal | 📝 Design pronto | Criar 5 endpoints AJAX e adicionar HTML em cad.php |
| Aprovação Clientes | 📝 Design pronto | Implementar ajax_aprovar_cliente_temp.php |
| Múltiplos XMLs | ❓ Próximo | Após validação individual funcionar |

---

## 🚨 Erros Comuns & Soluções

### ❌ "Este arquivo XML já foi importado"
**Causa:** Hash duplicado em `tms001_nf_importacao`  
**Solução:** Verificar `SELECT * FROM tms001_nf_importacao WHERE hash_arquivo = 'xxx'`

### ❌ "Cliente não encontrado em dim_cliente"
**Esperado!** Sistema cria em `tms001_cliente_temporario` (status=0)  
**Solução:** Usuário aprova em modal de validação

### ❌ "Constraint violation: chave_acesso"
**Causa:** Mesma NF (chave_acesso) importada 2x  
**Solução:** Usar HASH para prevenir, verificar duplicatas antes

### ❌ "FK error: idemitente não existe"
**Causa:** Cliente não foi criado/encontrado corretamente  
**Solução:** Verificar lógica em `buscar_ou_criar_cliente()`

---

## 🔐 Segurança - Checklist

✅ Hash SHA256 previne re-import  
✅ pg_escape_string() contra SQL injection  
✅ Validação de tipo (XML only)  
✅ Validação de tamanho (5MB max)  
✅ Auditoria completa  
✅ Try/catch para erros  
✅ UNIQUE constraints no BD  

---

## 📱 URLs Importantes

| URL | Método | Descrição |
|-----|--------|-----------|
| `/tms010_operacao/import_xml.php` | POST | Upload e armazenamento |
| `/tms010_operacao/teste_xml.php` | GET | Testar parser |
| `/tms010_operacao/cad.php` | GET | Formulário principal |
| `/tms010_operacao/ajax_obter_nf.php` | GET | [TODO] Buscar NF do banco |
| `/tms010_operacao/ajax_vincular_nf_viagem.php` | POST | [TODO] Vincular NF |
| `/tms010_operacao/ajax_aprovar_cliente_temp.php` | POST | [TODO] Aprovar cliente |

---

## 📊 Estrutura de Resposta do Parser

```javascript
{
  ide: {
    numero: "123456",
    serie: "1",
    chave_acesso: "35210101234567...",
    data_emissao: "2024-01-15"
  },
  emit: {
    cnpj: "12.345.678/0001-90",
    razao_social: "Empresa X LTDA",
    endereco: { logradouro, numero, bairro, cidade, uf, cep }
  },
  dest: { cnpj, razao_social, endereco, ... },
  transp: { modo, volume_total, inicio, fim },
  itens: [
    { numero, codigo, descricao, quantidade, valor_unitario, ... },
    ...
  ],
  total: {
    valor_total: 5000.00,
    valor_frete: 500.00,
    valor_icms: 1000.00,
    valor_ipi: 0.00,
    peso_total: 1000.00,
    ...
  }
}
```

---

## 🎯 Próximas Ações (Ordem)

1. **Executar SQL:**
   ```bash
   psql -U postgres -d SAG -f MODELO_BANCO_DADOS.sql
   ```

2. **Testar import_xml.php:**
   ```bash
   curl -X POST -F "arquivo=@exemplo.xml" http://localhost/tms010_operacao/import_xml.php
   ```

3. **Criar 5 endpoints AJAX:**
   - `ajax_obter_nf.php`
   - `ajax_obter_itens_nf.php`
   - `ajax_obter_clientes_temp.php`
   - `ajax_vincular_nf_viagem.php`
   - `ajax_aprovar_cliente_temp.php`

4. **Adicionar modal HTML em cad.php**

5. **Testar fluxo completo**

---

## 📞 Documentação Completa

- **Banco de Dados:** `MODELO_BANCO_DADOS_EXPLICADO.md`
- **Armazenamento:** `IMPLEMENTACAO_ARMAZENAMENTO_NF.md`
- **Frontend:** `TELA_VALIDACAO_NF.md`
- **Status:** `STATUS_COMPLETO.md`

---

## 🎓 Dicas & Truques

### Formatar CNPJ
```php
function formatarCNPJ($cnpj) {
  $cnpj = preg_replace('/[^0-9]/', '', $cnpj);
  return substr($cnpj,0,2).'.'.substr($cnpj,2,3).'.'.substr($cnpj,5,3).'/'.substr($cnpj,8,4).'-'.substr($cnpj,12,2);
}
```

### Converter valor para moeda
```php
function formatarMoeda($valor) {
  return 'R$ ' . number_format($valor, 2, ',', '.');
}
```

### Validar chave NFe (44 dígitos)
```php
if (strlen(preg_replace('/[^0-9]/', '', $chave_acesso)) !== 44) {
  throw new Exception('Chave de acesso inválida');
}
```

### Limpar CNPJ/CPF
```php
$limpo = preg_replace('/[^0-9]/', '', $cnpj_cpf);
```

---

## ⚡ Performance

- Usar `tms001_nf_importacao.hash_arquivo` com INDEX (previne 2º acesso ao BD)
- Usar views para relatórios (`vw_nf_por_viagem`, `vw_nf_pendentes`)
- Lazy load de itens (paginação se muitos itens)
- Cache de clientes em dim_cliente (query mais frequente)

---

## 🚀 Deploy

```bash
# 1. Backup
pg_dump SAG > backup_nf.sql

# 2. Criar tabelas
psql -U postgres -d SAG -f MODELO_BANCO_DADOS.sql

# 3. Verificar
psql -U postgres -d SAG -c "SELECT COUNT(*) FROM tms001_notafiscal;"

# 4. Testar
curl -X POST -F "arquivo=@exemplo.xml" \
  http://localhost/tms010_operacao/import_xml.php

# 5. Monitorar
psql -U postgres -d SAG -c "SELECT status, COUNT(*) FROM tms001_nf_importacao GROUP BY status;"
```

---

**Última atualização:** 2024-01-15  
**Versão:** 2.0  
**Tempo de leitura:** 5 minutos ⚡
