Qualidade, recall e doação
Transições de lote (quarentena, bloqueio, recall), campanha de impacto e doação com baixa rastreável — o que a flag liga e o que já funciona só com leitura.
Status de lote que não atendem ATP/FEFO/OP/venda: QUARANTINE, EXPIRED, BLOCKED, RECALLED. Só ACTIVE (e validade nula ou ≥ hoje) sai.
Qualidade
Não altere status com PATCH /product-lot/:id. O PATCH recusa. Use:
| Ação | Rota | Body |
|---|---|---|
| Quarentena | POST /api/product-lot/:id/quarantine | { "reason": "mínimo 5 caracteres" } |
| Liberar | POST /api/product-lot/:id/release | idem |
| Bloquear | POST /api/product-lot/:id/block | idem |
Kanban: /apps/stock/lots/qa e GET /api/product-lot/{filialId}/qa.
Motivo é obrigatório (≥ 5). Fica auditoria no lote (quarantine_reason, block_reason, released_at, ator).
Inbound automático só com industrial.quality.inbound-quarantine. Sem a flag, a NF cria ACTIVE; o QA é um passo explícito.
RBAC documentado: quality.lot.release / quality.lot.block. O controller hoje autentica JWT + menu de produtos — o nome da permissão ainda não é gate.
Recall
A simulação não precisa de flag:
Resposta: saldo, depósitos, lotes da genealogia (PA/MP), OPs, clientes, NFs de saída, transferências, devoluções, doações (CFOP 5910/6910).
Abrir campanha precisa de industrial.recall.enabled:
Efeito: campanha OPEN (REC-######), snapshot, lotes da cadeia em RECALLED. Saem do ATP. Exemplo HML: REC-000001 no lote da farinha congelou o pão.
Encerrar não volta o lote para ACTIVE. Cada lote precisa de release com motivo.
Telas: /apps/stock/recall e /apps/stock/recall/:id. Não confundir com a fila Health.
Devolução de venda pode gravar lot_id em FAT071. Expedição FATEX01.lot_id ainda não é writer industrial.
Doação
Listagem funciona com a flag OFF. Postar exige industrial.donation.enabled.
| Campo | Regra |
|---|---|
reason | ≥ 5 caracteres |
recipientName | ≥ 3 |
items | pelo menos um; quantity > 0 |
emitFiscal | se true, NF de bonificação CFOP 5910/6910 (BONIFICACAO) |
cfop | opcional; default do tipo de movimento de bonificação |
Kardex: origem DONATION, documento DON-######. Sem FAAJ01. Contábil: D CMV / C estoque.
Cancelar: POST /api/lot-donation/:id/cancel { "reason": "…" }.
Telas: /apps/stock/donations.
Rastreio
Tela /apps/stock/lots/:id: origem (NF, OP, fornecedor) e destino (OP, PA, NF, cliente). Kardex paginado no mesmo lote.
Volta típica: cliente → NF de saída → lote PA → OP → lote MP → NF de entrada / fornecedor.
Recusas que devem aparecer
| Tentativa | HTTP | Mensagem típica |
|---|---|---|
Saída de lote RECALLED / quarentena | 400 | estoque insuficiente nos lotes / lote não permitido |
| POST recall com flag OFF | 400 | industrial.recall.enabled |
| POST doação com flag OFF | 400 | industrial.donation.enabled |
| POST recall lote inexistente | 404 | lote não encontrado |
| PATCH de status | 400 | use /quarantine, /release ou /block |
| Motivo curto | 400 | mínimo 5 caracteres |
