# Relatórios completos de pedidos de assinatura

## Objetivo

O relatório responde a quatro perguntas operacionais:

1. Que PDFs foram preparados e ainda não originaram qualquer pedido de assinatura?
2. Que pedidos foram enviados e continuam sem assinatura concluída?
3. Que documentos foram assinados e recebidos com sucesso no dossiê?
4. Quem preparou cada documento, de que forma e por que motivo?

A página está disponível em **Relatórios de assinaturas** para utilizadores `owner`, `admin` e `editor` com o módulo `workflow` ativo.

## Registos incluídos

O relatório une duas origens:

- **Pedidos de assinatura** da tabela `signature_requests`;
- **PDFs preparados sem pedido**, provenientes de `pdf_generations` com regiões `signature` ou `initials` e sem qualquer pedido associado.

Desta forma, um PDF preparado não desaparece do controlo apenas porque ainda não foi enviado.

## Regra “Considerado pendente?”

É considerado pendente quando ainda não existe um PDF assinado recebido e o processo não foi encerrado por cancelamento ou recusa.

| Estado | Pendente? | Interpretação |
|---|---:|---|
| Preparado sem envio | Sim | PDF pronto, mas pedido ainda não criado |
| Preparado | Sim | Pedido criado, envio inicial não confirmado |
| Enviado | Sim | Convite enviado, ainda não aberto |
| Aberto | Sim | Destinatário abriu o pedido |
| OTP pendente/verificado | Sim | Identificação em curso ou concluída |
| A processar | Sim | Assinatura submetida, PDF final em geração |
| Falhou | Sim | A aplicação/arquivo precisa de intervenção |
| Expirado | Sim | Continua sem assinatura; deve ser reemitido |
| Assinado com documento em falta | Sim | O estado lógico não corresponde a um PDF recebido |
| Assinado e recebido | Não | PDF assinado arquivado e verificado |
| Recusado | Não | Processo encerrado por decisão do destinatário |
| Cancelado | Não | Processo encerrado administrativamente |

## Confirmação de receção

A conclusão não depende apenas de `status = signed`. O sistema exige:

- `signed_document_id` associado;
- ficheiro presente no disco privado;
- início do ficheiro igual a `%PDF-`;
- checksum SHA-256 igual ao checksum guardado;
- `receipt_verified_at` preenchido.

O worker que aplica a assinatura grava imediatamente `signed_document_received_at`, `receipt_checked_at` e `receipt_verified_at`. O scheduler volta a confirmar a integridade diariamente.

Execução manual:

```bash
php artisan signatures:verify-receipts
```

Limitar a uma organização:

```bash
php artisan signatures:verify-receipts --tenant=123
```

Rever novamente documentos já validados:

```bash
php artisan signatures:verify-receipts --force
```

Uma falha não remove o documento nem altera silenciosamente o pedido. São preenchidos `receipt_failure_code` e `receipt_failure_message`, ficando a anomalia visível no relatório.

## Preparação manual e automática

As gerações e pedidos guardam:

- `prepared_at`;
- `preparation_origin`: `manual`, `automatic`, `import`, `api` ou `workflow`;
- `preparation_reason`;
- utilizador em `requested_by` ou `created_by`.

Nos formulários de geração de PDF e criação de pedido existe um campo para descrever o motivo. Registos antigos recebem uma explicação padrão durante a migration.

## Métricas

O painel apresenta:

- total no filtro;
- total considerado pendente;
- PDFs preparados sem envio;
- enviados e não abertos;
- em interação/processamento;
- assinados e recebidos;
- anomalias de receção;
- fora de prazo;
- falhas;
- fechados sem assinatura;
- antiguidade dos pendentes.

## Filtros

É possível filtrar por:

- texto livre;
- estado principal;
- pendente sim/não;
- estado de receção;
- estado do envio;
- origem da preparação;
- dossiê;
- modelo PDF;
- utilizador que preparou;
- intervalo de preparação;
- apenas fora de prazo.

## Exportações

### CSV

- codificação UTF-8 com BOM;
- separador `;`;
- todos os filtros atuais são respeitados;
- valores iniciados por `=`, `+`, `-` ou `@` são neutralizados contra formula injection.

### XLSX

Contém:

- folha **Resumo** com métricas, antiguidade e filtros;
- folha **Pedidos** com detalhe completo;
- cabeçalho destacado;
- primeira linha fixa;
- autofiltro;
- datas Excel reais com formato `dd/mm/yyyy hh:mm`;
- texto escrito explicitamente como texto, sem execução de fórmulas.

O limite de exportação é configurado por:

```dotenv
SIGNATURE_REPORT_MAX_EXPORT_ROWS=50000
```

## Índices e desempenho

A migration acrescenta índices por organização sobre:

- data de preparação;
- origem da preparação;
- data de receção do documento assinado.

A listagem usa uma união SQL paginada em vez de carregar todos os registos em memória. As exportações usam cursor e limite configurável.

## Atualização

```bash
composer install
php artisan migrate --force
php artisan optimize:clear
php artisan queue:restart
```

O scheduler deve permanecer ativo:

```bash
php artisan schedule:work
```
