# ClientFlow v3.4 — Documentos, PDFs e Outbox Operacional

Esta versão é incremental sobre a v3.3 e foca-se em reduzir a necessidade de usar o terminal para operar integrações.

## Alterações principais

### Documentos Jasmin

- Adicionados botões no cartão **Documentos Jasmin** da oportunidade:
  - **Atualizar nº**: volta a consultar o Jasmin e atualiza número/série/valor do documento local.
  - **PDF**: tenta obter o PDF do orçamento ou da fatura diretamente via API Jasmin.
- Mantém atualização manual; não há auto-refresh contínuo do cartão.

### Outbox operacional

- Página `/outbox` remodelada para uso operacional.
- Filtros por estado: todas, pendentes, enviadas, falhadas e ignoradas.
- Filtros por sistema: Jasmin, Packlink, Chatwoot, Mautic e Odoo.
- Ações na UI:
  - Reprocessar
  - Ignorar
  - Ver detalhe/payload/erro
- Novo estado `ignored` suportado na outbox.

### Produtos / Jasmin

- Página `/products/validate-jasmin` para validar se os artigos configurados em `products.jasmin_sales_item` existem no Jasmin.
- Botão **Validar artigos Jasmin** no catálogo de produtos.
- Mantém a separação:
  - `products.sku` = SKU interno/Odoo
  - `products.jasmin_sales_item` = artigo Jasmin usado em orçamentos/faturas

## Validações mantidas

Antes de criar orçamento Jasmin, continua a validar:

- Cliente associado à oportunidade
- NIF do cliente
- Nome fiscal
- Morada/código postal/cidade quando for necessário criar cliente no Jasmin
- Pelo menos um produto ativo na oportunidade
- Todos os produtos com `jasmin_sales_item`
- Preços unitários positivos

## Notas operacionais

- A obtenção de PDF depende dos endpoints de impressão do Jasmin estarem disponíveis no tenant.
- Se o PDF falhar, a página devolve erro textual sem afetar o documento já criado.
- A outbox Jasmin deve ser processada por timer systemd ou manualmente com `scripts/process_outbox.py`.

## Validação técnica

Executado na geração desta versão:

```bash
python -m py_compile app/*.py scripts/*.py
python -m pytest -q
```

Resultado: `4 passed`.
