# Refatorar: Lógica de Negócio em Designacoes.php

Inventário de tudo que **não é responsabilidade de um controller** e precisa ser extraído.

Um controller deve apenas: receber input → delegar para uma classe especializada → renderizar a resposta.

---

## 1. `calcularEstatisticasPainel()` — linhas 676–847 (~172 linhas)

**Problema:** computação de domínio pura embutida no controller.

O método itera sobre itens e calcula:
- contagem de itens por status (`concluido`, `ocorrencia`, `pulado`, `em_andamento`, `pendente`)
- totais de quantidade bipada (manual vs. scan)
- cubagem total, bipada e em ocorrência
- agrupamento e progresso por gôndola
- cálculo de gôndolas físicas (parseando frações como `1/2`)
- percentual de progresso geral

Nada disso é responsabilidade de um controller. Tudo é regra de domínio sobre como agregar e interpretar o estado de itens de uma missão.

**Onde pertence:** `Laboratorios/MissaoPainelEstatisticas.php` — recebe `array $itens` e `array $strategyConfig`, retorna o array de estatísticas.

---

## 2. `prepararDadosLista()` — linhas 853–988 (~135 linhas) + código morto 989–1127

**Problema:** orquestração de múltiplas fontes de dados (pipeline de enriquecimento) + código morto.

O método atual (parte ativa até a linha 988) faz:
- detecção de `tipo_entrega` por `origem` da missão (`ROMANEIO`, `ENTREGA`, `RETIRA`, `PEDIDO`)
- batch fetch de romaneios via satélite `Romaneios`
- enriquecimento com dados do ERP via `AntigoRomaneio::find()` (acesso direto a model ERP)
- ordenação: status → prioridade

**Código morto (linhas 989–1127):** bloco inteiro após o `return` na linha 975 — nunca é executado. Inclui batch fetch de `ProcessoStatusMovimentacao`, `RomaneioVeiculo`, `Veiculo` e segundo `usort`. Deve ser deletado.

**Onde pertence:** `Laboratorios/MissaoListaEnriquecedor.php` — recebe `array $missoes` e a `galaxiaRoute` para os satélites, retorna `['missoes' => ..., 'estatisticas' => ...]`.

---

## 3. `buscarProdutos()` — linhas 1195–1290 (~95 linhas)

**Problema:** lógica de busca em 3 passes com deduplicação + saída direta com `echo`/`exit`.

O método executa 3 chamadas separadas ao satélite `Produtos` (por código, por código de barras, por descrição) e deduplica os resultados por `id`. Isso é uma estratégia de busca multi-critério — regra de domínio.

Além disso, usa `echo json_encode(...); exit;` ao invés de retornar pelo framework, quebrando o contrato do controller.

**Onde pertence:** `Laboratorios/BuscaProdutosLab.php` (ou mover a lógica para `Satelites/Produtos` com suporte a busca textual). O controller deve apenas chamar e retornar pelo framework.

---

## 4. `verificarGestorLogistico()` — linhas 1474–1501 (~28 linhas)

**Problema:** controle de acesso/autorização embutido no controller.

Verifica via `GoldieUsers` API se o usuário logado tem `gestor_logistico = 1`. Regra de autorização não é responsabilidade do controller. É chamada em três pontos diferentes (`lista()`, `painel()` duas vezes).

**Onde pertence:** um Trait `VerificaGestorLogisticoTrait` em `Satelites/Traits/` ou um método estático em `GoldieUsers`. Hoje já existe `EnriqueceMissaoTrait` com lógica similar de usuário — pode ser consolidado.

---

## 5. `verItens()` — linhas 1295–1346 (~52 linhas)

**Problema:** enriquecimento de dados inline + saída direta com `echo`/`exit` + ineficiência.

Após buscar os itens via satélite, o método enriquece com nomes de operadores buscando **todos os usuários** via `GoldieUsers` e filtrando em PHP. O painel (`painel()`) usa o correto `MissoesConsultas::buscarNomesUsuarios($ids)` — o `verItens()` deveria usar o mesmo.

Usa `echo json_encode(...); exit;` direto, quebrando o contrato do framework.

**Onde pertence:** o enriquecimento de operadores por IDs deve usar `MissoesConsultas::buscarNomesUsuarios()` como já feito no `painel()`. O controller só deve montar e retornar o HTML.

---

## 6. `detalhesFaltas()` — linhas 1530–1603 (~74 linhas)

**Problema:** acesso direto a model + parse de JSON de domínio + agrupamento de dados.

O método instancia `MissaoLogisticaItem` diretamente, executa query com filtros de domínio (`status='ocorrencia'` + operador JSON `->>`), parseia os campos `dados_coletados` e `dados_adicionais`, calcula quantidades (`qtdEsperada - qtdBipada`) e agrupa por pedido.

Todo esse trabalho é montagem/transformação de dados de domínio.

**Onde pertence:** `Laboratorios/DetalhesFaltasLab.php` — recebe `int $missaoId`, retorna `['pedidosFaltas' => ..., 'totalItensFalta' => ..., 'totalFalta' => ..., 'totalPedidos' => ...]`. O controller apenas chama o laboratório e renderiza.

---

## 7. `start()` — efeito colateral de domínio no roteador (linhas 164–180)

**Problema:** operação de domínio (`garantirDiaAberto`) executada como efeito colateral do roteamento.

O roteador chama o satélite `MissoesDias::garantirDiaAberto` toda vez que a tela é acessada no dia de hoje. Isso é uma regra de negócio ("o dia deve estar aberto ao acessar a lista") misturada com a responsabilidade de roteamento.

**Onde pertence:** idealmente em um middleware/hook de inicialização, ou no satélite `MissoesDias` como uma verificação lazy. O controller não deveria ser responsável por garantir invariantes de domínio.

---

## 8. `lista()` — acesso direto a model `OcorrenciaSonda` (linhas 320–332)

**Problema:** instanciação direta de model de outra constelação.

```php
$sondaOcorrencia = new \GalaxiaMissoes\Logistica\sinais\Ocorrencias\Sondas\OcorrenciaSonda();
$sondaOcorrencia->all();
$quantidadeOcorrenciasPendentes = (int) $sondaOcorrencia->findAny(...);
```

O controller cruza a fronteira da constelação acessando o model de Ocorrências diretamente. Deveria existir um satélite ou sonda de Ocorrências com um método `contarPendentes()`.

**Onde pertence:** `Satelites/OcorrenciasConsultas` ou equivalente — expõe `contarPendentes(): int`.

---

## 9. `analisarCarregamento()` — HTML inline no controller (linhas 1404–1448)

**Problema:** string HTML de confirmação gerada inline no controller.

O bloco do tipo `CARREGAMENTO` gera ~40 linhas de HTML inline com estilos embutidos diretamente no controller. Isso é apresentação no controller.

**Onde pertence:** extrair para uma view parcial `forms/confirmar_carregamento_simples.php`. O controller inclui a view, não gera HTML.

---

## Resumo

| Método / Bloco | Tipo de violação | Destino sugerido |
|---|---|---|
| `calcularEstatisticasPainel()` | Computação de domínio | `Laboratorios/MissaoPainelEstatisticas` |
| `prepararDadosLista()` (parte ativa) | Pipeline de enriquecimento | `Laboratorios/MissaoListaEnriquecedor` |
| Código morto pós-`return` (~139 linhas) | Código morto | Deletar |
| `buscarProdutos()` | Lógica de busca + `echo`/`exit` direto | `Laboratorios/BuscaProdutosLab` |
| `verificarGestorLogistico()` | Autorização | Trait ou serviço dedicado |
| `verItens()` | Enriquecimento inline + `echo`/`exit` direto | Usar `MissoesConsultas::buscarNomesUsuarios` |
| `detalhesFaltas()` | Acesso a model + parse JSON + agrupamento | `Laboratorios/DetalhesFaltasLab` |
| `start()` garantirDiaAberto | Efeito colateral de domínio no roteador | Middleware / hook de inicialização |
| `lista()` OcorrenciaSonda direto | Acesso cross-constelação a model | Satélite `OcorrenciasConsultas` |
| `analisarCarregamento()` HTML inline | Apresentação no controller | View parcial `forms/confirmar_carregamento_simples.php` |
