# Alocação WMS — Fluxo Simplificado (Bipagem)

- **Data:** 2026-06-22
- **Status:** Aprovado para implementação
- **Escopo:** Frontend apenas (`sinais/App/html/alocacaowms/item.js` + `item.php`)
- **Backend:** Sem alteração

---

## 1. Contexto e problema

A tela de execução da Alocação WMS (`/missao/logistica/app/alocacaowms/{id}`) hoje
funciona como um **assistente de 2 passos**:

1. O operador escolhe um modo (Produto / Endereço).
2. Bipa **dois** códigos (um produto e um endereço WMS), em qualquer ordem.
3. Um botão **Confirmar** grava uma linha em `wms_alocacoes` e marca o item como
   `concluído` de uma vez.

O JS atual (`item.js`) tem duas "espertezas" que causam fricção e erro:

- **Inferência automática de campo** (`_decidirAlvo` / `_campoDoPasso`): o sistema
  tenta adivinhar se o código bipado é produto ou endereço pela posição/heurística.
- **Avanço automático de passo** (`_avancarPasso`): depois de preencher um campo,
  o foco pula sozinho para o outro.

Na prática isso troca o contexto sem o operador pedir, e às vezes joga o código no
campo errado. O fluxo desejado é **controle 100% manual, sem adivinhação**, focado
em velocidade e baixa fricção.

## 2. Decisões tomadas (brainstorming)

| # | Decisão | Escolha |
|---|---------|---------|
| 1 | Modelo de dados | **Manter o atual**: 1 Confirmar = 1 alocação, item `concluído`. Só corrigir a inferência automática. |
| 2 | O que o "modo" controla | **Modo = campo-alvo de todo bipe.** Em modo Produto, todo código vai pro campo Produto; em modo Endereço, todo código vai pro campo Localização. O modo nunca muda sozinho. |
| 3 | Quantidade ("+1 por bipe") | **Bipar soma a quantidade.** Cada bipe do mesmo produto incrementa a quantidade (`+fator`) antes do Confirmar. Continua 1 Confirmar / 1 item. |
| 4 | Toque no outro campo | **Redireciona 1 bipe e volta.** O toque manda só o próximo bipe pro campo tocado; depois volta sozinho pro campo do modo. |
| 5 | Bipou produto diferente no meio da contagem | **Avisa e ignora.** Toast "Confirme ou limpe o produto atual" e mantém o produto/contagem; operador usa Limpar (✕) pra trocar. |

## 3. Escopo

### 3.1 O que NÃO muda (backend intacto)
- Tabela `wms_alocacoes` e Sonda `WmsAlocacaoSonda`.
- `MissoesBipagem::alocarLocalizacao` (mesmo payload: `missao_id`, `produto_id`,
  `localizacao_codigo`, `origem_leitura`, `quantidade`).
- `ConfirmarAlocacaoLaboratorio`, `ConfirmarAlocacaoValidator`, `WmsLocalizacaoSonda`.
- Migrations, enums, testes de backend.
- O backend recebe a `quantidade` **final acumulada** pelo front, igual a hoje.

### 3.2 O que muda (frontend)
- `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.js` — lógica de
  roteamento dos bipes, acumulação de quantidade, render do indicador de modo.
- `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php` — troca o
  indicador de passos (`#wms-step-indicator`) por um indicador de modo; selo `×N`;
  strings i18n.

## 4. Modelo de interação (detalhado)

O modo selecionado é o **campo-alvo fixo** de todo bipe. Regra de alvo:

```
alvoAtual = override_por_toque  ||  (modo === 'produto' ? 'produto' : 'localizacao')
```

- **Modo Produto:** todo código bipado é resolvido como produto
  (via `codigosBarrasMap` / fallback produto).
- **Modo Endereço:** todo código bipado é tratado como localização WMS.
- O modo **persiste** entre confirmações e reloads (sessionStorage `wms_aloc_modo_<missaoId>`,
  já existente). Após Confirmar (que dá reload), o operador continua no mesmo modo.
- **Sem inferência de conteúdo. Sem avanço automático de passo.** O modo só muda
  quando o operador clica em "Trocar modo".

### 4.1 Toque pra trocar de campo (override pontual)
- Tocar no campo oposto ao do modo redireciona **apenas o próximo bipe** para ele.
- Após preencher esse campo, o alvo **volta sozinho** para o campo do modo.
- Exemplo: em modo Produto, o operador toca em Localização → bipa o endereço →
  o endereço é gravado → o alvo volta a ser Produto. Não precisa trocar o modo inteiro.
- O input manual (digitar) por campo continua disponível via o mesmo toque.

### 4.2 Remoções no `item.js`
- `_decidirAlvo()` — substituído por `_alvoAtual()` (regra acima).
- `_campoDoPasso()` e a noção de `estado.passo` (wizard) — removidos.
- `_avancarPasso()` — removido.
- Render dos "step pills" — substituído por render do indicador de modo.

## 5. Quantidade (soma pelos bipes)

- **1º bipe** do produto → `quantidade = fator` resolvido do código (ex.: caixa = 12).
- **Bipe repetido do mesmo produto** → `quantidade += fator`.
- O campo Quantidade (`#wms-quantidade`) continua **editável manualmente**; o
  operador pode sobrescrever o valor acumulado.
- **Seleção pela lista** (toque no card, sem código de barras) → quantidade começa
  **vazia**; o operador bipa pra contar (`+fator`) ou digita.
- Selo `×N` perto do produto mostra quantas unidades entraram na confirmação atual.
- Sugestão de código de barras (fluxo existente) permanece igual.

## 6. Regras de borda

| Situação | Comportamento |
|---|---|
| Bipe em modo Produto, nenhum produto selecionado | Seleciona o produto, `quantidade = fator`. |
| Bipe do **mesmo** produto já selecionado | `quantidade += fator`. |
| Bipe de produto **diferente** com quantidade acumulada | **Toast "Confirme ou limpe o produto atual" e ignora.** Mantém atual. Trocar = botão Limpar (✕). |
| Bipe em modo Endereço (ou override por toque) | Define/substitui a localização. Override volta pro campo do modo. |
| Código de produto não reconhecido | Mantém o comportamento atual (tenta lista; senão grava como código cru / mensagem). |
| Localização inexistente na base | Backend rejeita no Confirmar (validator, sem alteração). |

## 7. UI (`item.php`)

- **Tela inicial de modo** (Produto / Endereço): mantida.
- **Indicador de modo** (no lugar de `#wms-step-indicator`): mostra
  "Bipando: **PRODUTO**" (ou ENDEREÇO) + botão *Trocar modo*; destaca o campo-alvo
  atual (incluindo o override pontual por toque).
- **Campos Produto e Localização:** ambos sempre visíveis; o destaque (`.ativo`)
  segue o alvo atual.
- **Quantidade:** mostra o valor acumulado; selo `×N` de unidades no card do produto.
- **Botão Confirmar:** habilita quando há produto **e** localização (inalterado).

## 8. i18n

Strings novas via `show('texto em PT literal')` (chave = md5 do texto) e adicionadas
aos três arquivos `linguagens/{pt-br,en,es}.json`. Strings previstas:
"Bipando", "Trocar modo", "Confirme ou limpe o produto atual", rótulo do selo de
unidades. Validar no navegador após o auto-harvest.

## 9. Testes e verificação

- **Backend:** sem mudança → testes existentes seguem válidos.
- **JS:** sem harness de unidade no repo → verificação **manual no navegador**:
  1. Modo escolhido **gruda** (não muda sozinho após bipe nem após Confirmar/reload).
  2. Bipe **nunca** vai pro campo errado (modo Produto só preenche Produto, etc.).
  3. Toque em campo oposto redireciona **1 bipe** e volta.
  4. Quantidade **soma** a cada bipe do mesmo produto (`+fator`); editável na mão.
  5. Produto diferente → **toast + ignora**.
  6. Confirmar grava normalmente e marca item `concluído`.

## 10. Fora de escopo

- Qualquer mudança no modelo de dados, no acúmulo por linha, ou em status de item.
- **Rastreabilidade por bipe individual:** continua **não** persistida — grava-se a
  `quantidade` agregada em uma linha por Confirmar (mesma granularidade de hoje).
  Se rastreio por bipe for necessário no futuro, vira outro projeto (1 linha por unidade).

## 11. Riscos / tradeoffs

- **Mais toques por item:** com modo = campo-alvo fixo, preencher os dois campos
  exige o override por toque (ou trocar de modo). Mitigado pelo override pontual
  (toca, bipa, volta) e pela seleção via lista.
- **Acúmulo só no front:** a quantidade vive no estado do JS até o Confirmar. Um
  reload/refresh antes de confirmar **zera** a contagem em andamento (igual a hoje,
  já que nada é gravado antes do Confirmar).
