# Implementação frontend — alocacao-wms

## Views criadas

- `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/menu.php` (+ `menu.js`) — tela de início da missão (estado `iniciar`): briefing, badge de missão, contagem de itens pendentes, flag de quantidade obrigatória, botão "Iniciar Alocação" via Galaxia acaoElemento. Tema Indigo. Incluído diretamente por `item.php` via `include` quando `$estado === 'iniciar'`.

- `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php` (+ `item.js`) — tela de execução principal com três estados:
  - `iniciar` → delega ao `menu.php`
  - `em_andamento` → barra de progresso, dois campos de scan (produto + localização WMS), botão confirmar (desabilitado até ambos preenchidos), campo de quantidade (obrigatório ou opcional por missão), lista de itens pendentes/concluídos com busca, animação de item ativo, toast de feedback
  - `concluido` → tela de celebração com total de itens e botão "Concluir Missão" ou "Voltar"
  - `erro` → tela de bloqueio

- `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/lista.php` (+ `lista.js`) — thin wrapper que delega para `html/shared/lista_unificada.php`. Na prática o handler chama `lista_unificada` diretamente via `renderMissionListing`; este arquivo serve como ponto de entrada alternativo e documentação de variáveis.

## Lógica de bipagem (item.js)

Implementação completa do fluxo AC3.1 (qualquer ordem):

- **Scanner hardware**: input fantasma `#wms-scanner-input` com autofocus, acumula caracteres por 120 ms e processa ao detectar pausa ou Enter.
- **Roteamento de código**: se produto já está fixado (item selecionado na lista) → próximo código vai para localização; se nenhum campo preenchido → tenta resolver o código contra a lista de itens pelo `data-produto-codigo`; campo ativo (tap) define destino.
- **Entrada manual**: tap no campo abre `<input class="wms-input-manual">` inline; confirmado com Enter ou blur.
- **Origem da leitura (AC3.3)**: `'codigo_barras'` para scanner, `'manual'` para digitação. Se qualquer campo for manual, `origem_leitura='manual'` é enviado.
- **Botão confirmar (AC3.2)**: desabilitado enquanto produto ou localização estiverem vazios. Com `quantidadeObrigatoria=true`, também requer quantidade > 0.
- **Disparo**: constrói botão temporário com os atributos do botão fantasma PHP + parâmetros extras (`produto_id`, `localizacao_codigo`, `origem_leitura`, `quantidade`) e dispara `click` via jQuery para o mecanismo Galaxia interceptar. O backend (`MissoesBipagem::alocarLocalizacao`) valida e chama `atualizarPagina` em caso de sucesso.
- **Feedback**: toast fixado no topo com animação slide; marcação visual de erro nos campos com `classe erro-campo` + shake animation.

## Forms

Não há forms autônomos para este fluxo — a confirmação usa o padrão de botão com `acaoElemento` do Galaxia (mesmo padrão de `biparItem` em Separação/Carregamento).

## i18n

Chaves adicionadas nas 3 línguas (`pt-br.json`, `en.json`, `es.json`):

| Chave (md5) | pt-br | en | es |
|---|---|---|---|
| `e829f3b1d6910638de872f580df54aa6` | Alocação WMS | WMS Allocation | Asignación WMS |
| `8ccc99cfe715b5e2e44f31f594250b09` | Bipe o código de localização WMS e o código do produto, em qualquer ordem | Scan the WMS location code and the product code, in any order | Escanee el código de ubicación WMS y el código del producto, en cualquier orden |
| `a4ebccce8f56860ab9ee78e79890f8a3` | Itens pendentes | Pending items | Ítems pendientes |
| `3fdd8edc614a27f1d229e51e3829f0eb` | Quantidade obrigatória | Quantity required | Cantidad obligatoria |
| `867850056c53df64e28385d5c17b28e0` | Iniciar Alocação | Start Allocation | Iniciar Asignación |
| `7dc81367e98587ec7ae30d8400a18816` | Missão não iniciada — toque em Iniciar para começar | Mission not started — tap Start to begin | Misión no iniciada — toque Iniciar para comenzar |
| `7ced87f16205b8ece787f73bfd518b81` | Tela de Alocação WMS | WMS Allocation Screen | Pantalla de Asignación WMS |
| `5cfa97c98fb9541a5b0ce3f59c6a3426` | Missão concluída | Mission completed | Misión completada |
| `c0723ad0193b9b78d0cee5b3e96f10ee` | Todos os itens foram alocados | All items have been allocated | Todos los ítems han sido asignados |
| `6b626031a139ebb302505decd5dc4fcb` | Concluídos | Completed | Completados |
| `c7d559f91cad5c1da858dd83650271f8` | Voltar para missões | Back to missions | Volver a misiones |
| `025c35185b0fc71258a8a20daa636c3e` | Confirmar alocação | Confirm allocation | Confirmar asignación |
| `ddfcda6314dd4bf1e7da03d9d50df22d` | Localização | Location | Ubicación |
| `8bf3a2270ff3790f27cbd9f1452f745a` | Produto | Product | Producto |
| `ee114961e9ea88d13ea20c52b21038df` | Aguardando leitura... | Awaiting scan... | Esperando escaneo... |
| `8ae0d2d4dd7fecb4726c027b80e9d8ad` | Limpar | Clear | Limpiar |
| `dc303a2827baa31e86545a68cf95989b` | Código do produto | Product code | Código del producto |
| `e2c09bcc87f13a7b2afb10971e89fd84` | Código da localização WMS | WMS location code | Código de ubicación WMS |
| `404eedacb60d7088d8929105cb102c95` | Quantidade | Quantity | Cantidad |
| `ffcdcc516ec6ea6692e46fc2cff25af4` | Pendentes | Pending | Pendientes |
| `773c61bf665eb9a2fb52fcf7537cb27b` | Buscar produto... | Search product... | Buscar producto... |
| `b99bc33d516a6d7ffaf8843b570c77e1` | Nenhuma missão de Alocação WMS pendente | No pending WMS Allocation missions | Sin misiones de Asignación WMS pendientes |

## Endpoints consumidos

O fluxo usa o mecanismo interno Galaxia (satélites), não REST `/api/v1`:

- **Listagem de missões**: `BaseHandler::renderMissionListing` → `MissoesLogisticas (leitura)` + `AlocacaoWmsListaStrategy`
- **Iniciar missão**: `MissoesStatus::iniciarMissao` via `acaoElemento` (botão menu.php)
- **Confirmar alocação**: `MissoesBipagem::alocarLocalizacao` via `acaoElemento` no botão fantasma `#btn-alocar-fantasma`
  - POST campos: `missao_id`, `produto_id`, `localizacao_codigo`, `origem_leitura` (`codigo_barras`|`manual`), `quantidade` (opcional)
  - Resposta sucesso: `{status: 'success', alocacao_id: int, item_id: int, missao_id: int}` + `atualizarPagina`
  - Respostas de erro (AC4.5): mensagem específica por motivo (missão inativa, sem permissão, produto fora da missão, localização inválida, quantidade obrigatória)
- **Finalizar missão**: `MissoesStatus::finalizarMissao` via `acaoElemento` (tela concluído)
- **Histórico (AJAX)**: `AlocacaoWms` dispatcher ação `historico` — GET `missao_id=int&produto_id=int` → `{ok: true, alocacoes: [...]}`

## Smoke test sugerido

1. Acessar `/missao/logistica/app/alocacaowms` → deve listar missões de Alocação WMS com tema Indigo (`#4f46e5`), estatísticas (Pendentes / Andamento / Concluídas / Total) e search bar.
2. Com uma missão em estado `pendente`, abrir `/missao/logistica/app/alocacaowms/{id}` → deve renderizar `menu.php` com briefing e botão "Iniciar Alocação".
3. Clicar em "Iniciar Alocação" → missão muda para `em_andamento`, tela muda para `item.php` com campos de scan.
4. **Fluxo scanner loc → produto (qualquer ordem)**:
   a. Simular bipagem de código de localização WMS (ex.: `C01-P02-A`): campo Localização preenche com classe `preenchido`.
   b. Simular bipagem do código do produto: campo Produto preenche, botão Confirmar habilita.
   c. Clicar em Confirmar → toast "Localização registrada" aparece, página recarrega, item sai dos pendentes e aparece nos concluídos.
5. **Fluxo inverso produto → loc**: tap em item da lista → produto fica ativo (ponto animado), campo Localização aguarda → bipar localização → Confirmar.
6. **Entrada manual**: tap no campo Localização → input inline aparece → digitar código → Enter → campo preenche com origem `manual`.
7. Com `quantidade_obrigatoria=true`: botão Confirmar permanece desabilitado até campo Quantidade > 0.
8. Bipar produto fora da missão → backend retorna erro → toast vermelho com mensagem específica, nenhum item é concluído.
9. Bipar localização inexistente na base `wms_localizacoes` → backend retorna erro → toast vermelho, item permanece pendente.
10. Após último item concluído → tela muda para estado `concluido` com botão "Concluir Missão".
11. Verificar `wms_alocacoes` no banco: linhas criadas com `integracao_erp='pendente'` e `integracao_wms='pendente'`.
12. Aguardar cron `wms_alocacao_integracao.php` (2 min) → verificar logs em `/tmp/genesis_wms_worker.log` e `/tmp/genesis_webhook.log`.
