# Controle completo de estoque

## Prompt

Implementar um fluxo completo de controle de estoque no frontend, backend e banco de dados, após auditoria integral da estrutura existente. A solução deve contemplar saldo inicial e custo unitário no produto, estoque e custo médio ponderado por empresa, operações configuráveis de entrada/saída/neutra, histórico imutável, finalização transacional e idempotente, bloqueio concorrente, vendas, compras, cancelamentos por estorno, devoluções, relatórios gerenciais, gráficos, filtros, exportações, isolamento por empresa, permissões e auditoria.

O saldo somente pode mudar por movimentação. Vendas e compras em rascunho não movimentam estoque; documentos finalizados não podem ser editados ou excluídos; cancelamentos devem gerar movimentos inversos vinculados aos originais. Deve haver validação de saldo negativo, precisão decimal, compatibilidade com registros legados, scripts SQL versionados e aplicados no desenvolvimento, além de testes para saldo inicial, entrada, saída, estorno, duplicidade, concorrência e isolamento entre empresas.

Criar o Portal de Compras seguindo o padrão do Portal de Vendas e as regras de CRUD do projeto. Criar relatórios de posição atual, movimentações, baixo estoque, custos e projeção de lucro, com gráficos e filtros por empresa. Preservar pagamentos, emissão fiscal, impressão e fechamento existentes. Ao final, listar arquivos, banco, decisões, riscos, testes e checklist. O build do frontend somente deve ser executado após confirmação.

## Resposta

Implementação concluída no frontend, backend e banco de desenvolvimento.

### Entrega funcional

- Saldo inicial e custo unitário no cadastro do produto; saldo zero é aceito e saldo positivo gera movimento `SALDO_INICIAL` vinculado à operação de sistema.
- Saldo, custo médio, estoque mínimo, última movimentação e versão de concorrência separados por produto e empresa.
- Saldo e custo médio somente leitura após o cadastro; endpoints legados de alteração direta foram bloqueados.
- Cadastro de operações ampliado com código, finalidade, direção, movimentação, custo, estoque negativo, fornecedor, cliente, empresa e operação inversa.
- Razão de estoque imutável com chaves idempotentes, saldos anterior/posterior, custos, usuário, documento e vínculos de estorno.
- Vendas finalizadas movimentam saída dentro da mesma transação do documento, registram custo/lucro e não podem ser reabertas, editadas ou excluídas diretamente.
- Portal de Compras com rascunho, edição, finalização, recebimento, histórico, fornecedor, cancelamento e entrada com custo médio ponderado.
- Cancelamentos geram movimentos inversos; devoluções parciais de compra e venda respeitam o acumulado devolvido.
- Tela e endpoint de ajuste positivo/negativo com justificativa, idempotência e auditoria.
- Histórico com paginação no backend, filtros completos e exportações CSV/PDF.
- Relatórios de posição, estoque mínimo/zerado, custo, receita e lucro potenciais, margem e gráficos; consultas isoladas pela conta e empresa sem N+1.
- Menus e endpoints sensíveis restritos ao perfil administrador, seguindo o padrão atual de permissões do sistema.

### Banco de dados

Scripts criados e aplicados no ambiente de desenvolvimento:

1. `database/2026-07-16-002-controle-completo-estoque.sql`: precisão decimal, custo médio, versão, unicidade produto/empresa, configuração de operações, compras, razão, auditoria, custos de venda e migração do legado.
2. `database/2026-07-16-003-devolucoes-parciais-estoque.sql`: documentos e itens de devolução parcial.
3. `database/2026-07-16-004-imutabilidade-historico-estoque.sql`: gatilhos que bloqueiam `UPDATE` e `DELETE` no razão.
4. `database/2026-07-16-005-operacoes-sistema-estoque.sql`: classificação de devoluções legadas e operações padrão de saldo inicial, devoluções e ajustes, com inversas.

Foram confirmados no banco: seis tabelas do novo domínio, dois gatilhos de imutabilidade, chave única `(id_produto, id_empresa)`, índices de saldo/custo/relatórios e ausência de resíduos dos testes.

### Arquivos criados

- `back/App/Services/EstoqueService.php`
- `back/App/Controllers/ComprasController.php`
- `back/App/Controllers/EstoqueController.php`
- `back/tests/StockFlowIntegrationTest.php`
- `back/tests/StockConcurrencyIntegrationTest.php`
- `front/src/views/app/compras/ComprasContainer.vue`
- `front/src/views/app/compras/CompraForm.vue`
- `front/src/views/app/compras/cadastro.vue`
- `front/src/views/app/compras/listagem.vue`
- `front/src/views/app/estoque/MovimentacoesEstoqueView.vue`
- `front/src/views/app/estoque/DevolucaoEstoqueView.vue`
- `front/src/views/app/estoque/AjusteEstoqueView.vue`
- os quatro scripts SQL listados acima
- este registro em `prompt/2026-07-16-controle-completo-estoque.md`

### Arquivos alterados

- Backend: `Routers/Routers.php`, `Controllers/VendasController.php`, `ProdutosController.php`, `OperacoesController.php`, `ProdutosEstoqueController.php`, `ProdutosMovimentacaoController.php`, `ReportsController.php`, `ContasUsuariosController.php` e `tests/run.php`.
- Frontend: `types/types.ts`, `services/apiService.ts`, `constants/routers.ts`, `components/CardSale.vue`, `components/CadastroDataTable.vue`, `composables/useSaleForm.ts`, cadastro de produtos, cadastro/listagem de operações e relatório de estoque.

### Decisões técnicas

- Custo médio ponderado com `DECIMAL`, sem `float`; saídas mantêm o custo vigente e estornos usam o vínculo com o movimento original.
- `SELECT ... FOR UPDATE`, versão otimista no saldo e chave única no razão para concorrência e idempotência.
- Movimento original nunca é apagado; correções são novos movimentos inversos.
- O identificador da conta é sempre obtido do JWT/request autenticado; filtros recebidos do cliente não podem trocar a conta.
- Operações legadas foram classificadas pelos campos fiscais/estoque existentes e, para devoluções, também pela descrição.
- Efeitos financeiros e fiscais legados foram preservados; a nova atomicidade cobre a finalização do documento e o estoque, sem reescrever os módulos fiscal, caixa e faturamento.

### Validações executadas

- `php tests/run.php`: **67 testes aprovados**.
- Cenários cobertos: saldo inicial zero/positivo, custo médio, compra, venda, saldo insuficiente, repetição idempotente, cancelamentos, devolução parcial, ajustes, histórico imutável, duas empresas e duas finalizações simultâneas.
- `php -l`: **122 arquivos PHP válidos**.
- `npm run lint`: **0 erros e 0 avisos**.
- `npm run type-check`: aprovado.
- Imports e rotas do frontend validados pela tipagem.
- `npm run build`: não executado, pois as regras do projeto exigem confirmação prévia e o build é opcional.

### Riscos e confirmações

- Recomenda-se revisar em homologação os CFOPs e a finalidade das operações legadas de cada conta, pois a migração preserva os dados fiscais e usa classificação compatível com os campos atuais.
- Transferências aparecem como finalidade configurável, mas não foi criado um documento dedicado de transferência entre empresas, pois o escopo detalhou documentos completos apenas para compras e vendas. Uma transferência futura deve gerar saída e entrada pareadas na mesma transação.
- Pagamentos, caixa e emissão fiscal continuam no fluxo legado; não foram reestruturados para evitar regressões fora do domínio de estoque.
- Falta somente a decisão do responsável sobre executar o build opcional do frontend.

### Checklist final

- [x] Produtos, saldo inicial e custo
- [x] Estoque isolado por empresa
- [x] Operações configuráveis e operações de sistema
- [x] Histórico imutável e auditoria
- [x] Transação, locks e idempotência
- [x] Compras e vendas integradas
- [x] Cancelamentos, estornos e devoluções parciais
- [x] Ajustes de entrada e saída
- [x] Relatórios, filtros, paginação, exportações e gráficos
- [x] Segurança de conta/empresa e permissões administrativas
- [x] Scripts aplicados no desenvolvimento
- [x] Testes, lint, tipagem e sintaxe
- [ ] Build opcional do frontend, aguardando confirmação

---

## Correção complementar — empresa no pagamento com cartão

### Prompt

Corrigir a mensagem incorreta “Cadastre uma empresa vinculada à conta para concluir o pagamento no cartão”, considerando que o cadastro da conta já exige uma empresa.

### Resposta

Corrigido o método `listarContasUsuario` em `front/src/services/apiService.ts` para carregar os relacionamentos `empresas` e `usuarios`. A tela de pagamento agora reconhece a empresa já cadastrada e pode montar os dados obrigatórios do titular para tokenização no Asaas. As validações de CNPJ, endereço e e-mail foram mantidas como proteção para dados legados ou incompletos.

---

## Correção complementar — aviso durante o teste gratuito

### Prompt

Durante o período de teste, não exibir alerta de sistema próximo do vencimento ou pedido de renovação. Informar apenas que a conta está no período de teste e que pode adicionar um plano.

### Resposta

O banner passou a aguardar o carregamento do contexto do plano/assinatura, eliminando a exibição momentânea e incorreta do aviso de renovação. Contas no plano gratuito ou com assinatura `TRIAL` recebem um aviso informativo: “Você está no período de teste gratuito e pode adicionar um plano a qualquer momento”, com ação para adicionar um plano. Alertas de vencimento e renovação permanecem exclusivos para assinaturas fora do período de teste.

---

## Correção complementar — avisos e bloqueio por vencimento

### Prompt

Exibir avisos somente nos cinco dias anteriores ao vencimento. Manter o aviso fixo durante os cinco dias posteriores. A partir do sexto dia, bloquear o uso do sistema e levar o usuário diretamente para a tela de pagamento ao entrar. Todos os textos apresentados devem ser simples e adequados a usuários comuns.

### Resposta

A regra foi unificada em todas as entradas do sistema:

- Antes de cinco dias para o vencimento, nenhum aviso é mostrado.
- Do quinto dia anterior até a data de vencimento, o aviso pode ser fechado.
- Do primeiro ao quinto dia após o vencimento, o aviso fica fixo e o usuário ainda pode utilizar o sistema.
- A partir do sexto dia após o vencimento, o acesso às demais telas é bloqueado e o usuário é levado para a página de pagamento ao entrar ou ao tentar continuar usando o sistema.
- O período de teste usa mensagens próprias e direciona para a escolha de planos.
- As mensagens de vencimento, pagamento e bloqueio foram reescritas em linguagem simples.

Foram ajustados o banner, login por senha, login pelo Google, conclusão do cadastro, proteção das páginas, resposta a bloqueio durante uma sessão aberta e validação do backend. Foram adicionados testes para confirmar que o quinto dia ainda permite acesso e o sexto dia bloqueia.

Validações: 69 testes aprovados, lint sem erros, tipagem aprovada e 122 arquivos PHP com sintaxe válida. O build continua aguardando confirmação.

---

## Correção complementar — aviso permanente no período de teste

### Prompt

O aviso da conta em período de teste deve permanecer visível durante todo o teste, mesmo quando faltarem mais de cinco dias para o término.

### Resposta

Corrigido. A regra de cinco dias continua valendo para avisos de pagamento das contas com plano contratado. Para contas em período de teste, o aviso informando que o usuário pode escolher um plano permanece sempre visível e não pode ser fechado enquanto o teste estiver ativo.

---

## Correção complementar — isolamento por conta e listagem de compras

### Prompt

Garantir que cada usuário veja somente os dados relacionados à própria conta, corrigindo as telas novas que exibiam empresas de outros usuários, especialmente Nova Compra. Remover do submenu as opções Nova Compra, Compras em Andamento e Histórico de Compras, reunindo tudo em Compras. Melhorar a listagem de compras, substituindo a tabela por uma lista de cartões de largura total e mantendo textos simples para usuários comuns.

### Resposta

As consultas de empresas, fornecedores, categorias, produtos e usuários passaram a aplicar no servidor a conta do usuário conectado, sem confiar no filtro enviado pela tela. A alteração de empresas, fornecedores, categorias e usuários também passou a confirmar que o cadastro pertence à conta atual. A consulta de compras já era separada por conta e recebeu uma verificação adicional nos dados relacionados.

No menu, Nova Compra, Compras em Andamento e Histórico de Compras deixaram de aparecer como opções separadas, sem remover suas rotas. A tela Compras reúne todos os estados e permite filtrá-los no diálogo de filtros. A listagem foi refeita em cartões responsivos de largura total, destacando fornecedor, documento, empresa, operação, quantidade de produtos, estado, data e total, com paginação e exportação para CSV e PDF.

Validações concluídas: lint sem erros ou avisos, tipagem aprovada, sintaxe dos arquivos PHP alterados válida e 69 testes aprovados. O build continua aguardando confirmação, conforme a regra do projeto.

### Correção após validação em execução

#### Prompt

Corrigir o erro que impediu o frontend de iniciar porque a rota principal e a rota filha receberam o mesmo nome `Compras`.

#### Resposta

O nome interno da rota de listagem foi alterado de `Compras` para `Lista de Compras`, pois o grupo principal já utiliza o nome `Compras` e os nomes internos precisam ser diferentes. O endereço da página e o funcionamento do menu foram preservados. Foram verificados os 69 nomes de rotas, sem outras duplicidades. Lint e tipagem também foram aprovados.

---

## Correção complementar — compra no mesmo padrão da venda

### Prompt

Melhorar a tela de compra para funcionar e ter aparência semelhante à tela de venda, sem os campos de cliente e vendedor, mantendo os demais comportamentos e adicionando pagamentos.

### Resposta

A tela de compra foi refeita com a mesma organização da venda: pesquisa e cadastro rápido de produtos, seleção de empresa, fornecedor e operação, lista visual dos itens, edição em janela, resumo lateral, total pago, valor restante, pagamentos e finalização. Os campos próprios da compra — fornecedor, documento e observação — foram preservados; cliente e vendedor não fazem parte da tela.

Foi criada a estrutura `compra_pagamentos`, vinculada à conta, compra e forma de pagamento. A mesma janela de pagamentos usada na venda passou a atender também compras, com textos adequados. O servidor impede pagamentos de outra conta, valores superiores ao restante, alterações após a finalização e finalização com pagamento incompleto. A compra continua movimentando o estoque somente quando é finalizada.

A migração `database/2026-07-16-006-pagamentos-compras.sql` foi aplicada no banco local. Foram aprovados lint, tipagem, sintaxe PHP e 70 testes automatizados. O carregamento do frontend também foi conferido no navegador sem novos erros da aplicação; a tela interna exige uma sessão autenticada para o teste visual completo. O build opcional não foi executado sem confirmação.

---

## Correção complementar — compra organizada em etapas

### Prompt

Reduzir a poluição visual da tela de compra. Organizar o processo em etapas: primeiro fornecedor e operação, depois somente os produtos e, por último, observação. O documento deve vir do cadastro do fornecedor e não precisa ser exibido junto aos demais campos.

### Resposta

A compra passou a ter três etapas claras:

1. **Informações:** escolha do fornecedor e da operação. A empresa usada é a que já está selecionada no sistema.
2. **Produtos:** pesquisa, inclusão, alteração e remoção dos itens, sem os demais campos misturados nessa área.
3. **Finalização:** observação opcional, resumo, pagamentos e conclusão da compra.

O documento deixou de ser solicitado na tela e agora é preenchido automaticamente com o documento do cadastro do fornecedor. O funcionamento já existente de produtos, pagamentos e entrada no estoque foi preservado.

Foram aprovados o lint e a verificação de tipos, sem erros ou avisos. O endereço local também foi aberto no navegador, mas a área interna não apresentou conteúdo sem uma sessão conectada. O build opcional continua aguardando confirmação.

---

## Correção complementar — fornecedor opcional na compra

### Prompt

O fornecedor deve ser opcional no cadastro da compra.

### Resposta

O fornecedor deixou de ser obrigatório em todo o fluxo da compra. A primeira etapa permite continuar somente com a operação, o campo pode ser limpo e nenhuma opção é escolhida automaticamente. Quando um fornecedor é informado, seu documento continua sendo preenchido automaticamente; sem fornecedor, o documento permanece vazio.

O salvamento, a consulta, a finalização e o cancelamento também passaram a aceitar compras sem fornecedor. As novas operações de compra já serão criadas com essa mesma regra, e as operações existentes foram atualizadas.

### Ajuste visual solicitado depois

#### Prompt

Remover o formato de assistente passo a passo, evitar rolagem na tela e retirar os grandes espaços ao redor dos elementos.

#### Resposta

O indicador de etapas e as telas separadas foram removidos. A compra voltou a ocupar uma única tela fixa, no mesmo formato da venda: fornecedor opcional e operação em uma faixa compacta, produtos na área principal e resumo ao lado. A observação aparece somente na janela de conclusão, junto com o acesso aos pagamentos. Os cartões e espaços amplos criados anteriormente foram retirados, e a página principal permanece sem rolagem.

### Segundo ajuste visual

#### Prompt

Usar a tela de vendas como referência direta, trocando cliente por fornecedor e vendedor por operação. Corrigir a compactação do conteúdo que deixou uma grande área vazia.

#### Resposta

A compra passou a repetir a mesma estrutura da venda: pesquisa e botão de novo produto no topo, fornecedor e operação na linha seguinte, lista de produtos ocupando toda a altura restante e resumo lateral com os botões de pagamentos e finalização no rodapé. A altura voltou a acompanhar toda a área disponível da página, eliminando o espaço vazio abaixo do conteúdo. A observação continua sendo solicitada somente ao confirmar a finalização.

Lint e verificação de tipos foram aprovados sem erros. A comparação pela sessão conectada do navegador não pôde ser feita porque o Chrome não estava aberto; a estrutura foi alinhada diretamente ao componente da tela de vendas e às imagens fornecidas.
