Restrições de Acesso e Edição para Vendedores
Versão: 1.0 Data: 2025-10-23 Status: ✅ Implementado
Visão Geral
Este documento consolida todas as regras de negócio implementadas para restringir as ações de usuários com perfil Vendedor no sistema SGE Nelmetais. O objetivo é garantir segurança, integridade de dados e rastreabilidade adequada de comissões e vendas.
Problemas Identificados
1. Empresa de Emissão Manipulável (Pedidos/Cotações)
Contexto: Ao criar ou editar pedidos e cotações, vendedores podiam selecionar livremente qualquer empresa de emissão.
Riscos: - Emissão de pedidos em nome de empresas não autorizadas - Perda de controle sobre qual empresa está emitindo documentos - Possível fraude fiscal
2. Acesso a Clientes Fora da Carteira (Destinatário)
Contexto: Na busca de destinatários, vendedores visualizavam e podiam selecionar todos os clientes da Nelmetais, não apenas os de sua carteira.
Riscos: - Violação de privacidade (LGPD) - Roubo de dados sensíveis de clientes - Vendedores acessando informações confidenciais de outros vendedores
3. Campo "Vendedor Comissionado" Editável (Clientes)
Contexto: Ao adicionar ou editar clientes, vendedores podiam alterar o campo "Vendedor Comissionado" livremente.
Riscos: - Manipulação de comissões - Atribuição incorreta de clientes na carteira - Perda de rastreabilidade de responsabilidade comercial
Regras de Negócio Implementadas
RN-001: Empresa de Emissão Bloqueada para Vendedores
Aplicação: Telas de adicionar/editar Pedidos e Cotações
Comportamento: - Vendedor deve usar apenas a empresa de seu contrato ativo - Campo "Empresa Emissão" é pré-selecionado automaticamente - Campo bloqueado para edição (disabled) - Validação backend impede manipulação via request
Exceção: - Vendedores sem empresa configurada: mensagem de erro clara
Não afetados: - Administradores e outros perfis: seleção livre de empresa
RN-002: Busca de Clientes Restrita à Carteira
Aplicação: Campo "Destinatário" ao criar/editar Pedidos e Cotações
Comportamento:
- Vendedor visualiza apenas clientes onde Cliente.VendedorId = FuncionarioId
- Busca por nome/CPF/CNPJ filtrada automaticamente
- Mensagem clara quando não há resultados: "Nenhum destinatário encontrado na busca"
Não afetados: - Busca de Fornecedores e Empresas: sem restrição - Administradores: visualizam todos os clientes
RN-003: Campo "Vendedor Comissionado" Bloqueado (Clientes)
Aplicação: Telas de adicionar/editar Cliente
Comportamento: - Campo "Vendedor Comissionado" é pré-selecionado com o ID do vendedor logado - Campo bloqueado para edição (disabled) - Validação backend garante que o valor não pode ser alterado
POST (Create):
- Sistema força o VendedorId do vendedor logado
POST (Edit):
- Sistema mantém o VendedorId original do cliente (não permite alteração)
Não afetados: - Campo "Vendedor Delegado": permanece editável - Administradores: podem alterar o vendedor comissionado livremente
Matriz de Comportamento
| Funcionalidade | Vendedor | Administrador | Campo Afetado |
|---|---|---|---|
| Empresa Emissão (Pedido) | Pré-selecionada + Bloqueada | Livre | EmpresaId |
| Busca Destinatário | Apenas carteira própria | Todos os clientes | Busca de Cliente |
| Vendedor Comissionado (Cliente) | Pré-selecionado + Bloqueado | Livre | VendedorId |
| Vendedor Delegado (Cliente) | Livre | Livre | VendedorDelegadoId |
Camadas de Proteção
Todas as restrições foram implementadas com múltiplas camadas de segurança:
1. Interface (View)
- Campos renderizados com
disabled="disabled" - Hidden inputs garantem envio de valores corretos
- Listas de seleção filtradas (mostra apenas opções permitidas)
2. Controller (Backend)
- Métodos GET: pré-seleção automática de valores
- Métodos POST: validação rigorosa antes de salvar
- Mensagens de erro claras e contextuais
3. Service Layer
- Métodos utilitários para identificar tipo de funcionário
- Métodos para obter dados específicos do vendedor (empresa, funcionário ID)
4. Repository Layer
- Filtros SQL aplicados nas consultas (WHERE clauses)
- Parâmetros opcionais para manter compatibilidade
Fluxo de Validação
Exemplo: Vendedor Adicionando Cliente
1. GET /cadastros/adicionar-cliente
├─ Controller detecta TipoFuncionario = Vendedor
├─ Obtém FuncionarioId do vendedor logado
├─ Define viewModel.VendedorId = FuncionarioId
└─ Define ViewBag.IsVendedor = true
2. View renderiza
├─ Campo VendedorId com disabled="disabled"
├─ Hidden input com value=FuncionarioId
└─ Label mostra nome do vendedor
3. POST /cadastros/adicionar-cliente
├─ Controller detecta TipoFuncionario = Vendedor
├─ Força viewModel.VendedorId = FuncionarioId (override)
├─ Validação: se valor foi alterado, rejeita
└─ Se OK, salva cliente
Mensagens de Erro
Vendedor sem Empresa Configurada (Pedidos)
"Não é possível cadastrar ou editar uma cotação ou pedido porque
o vendedor não tem nenhuma empresa ativa configurada para Emissão."
Vendedor Tentando Alterar Empresa (Pedidos)
Vendedor sem Clientes na Carteira (Destinatário)
Vendedor Tentando Alterar Campo Bloqueado (Cliente)
Identificação do Vendedor
Método Utilizado: ObterTipoFuncionarioLogado()
Lógica:
1. Obtém ApplicationUserId do usuário logado (GUID via Claims)
2. Busca Funcionario vinculado ao ApplicationUserId
3. Retorna TipoFuncionarioEnum do funcionário
Valores possíveis:
- TipoFuncionarioEnum.Vendedor (valor: 12)
- TipoFuncionarioEnum.Administrador
- Outros tipos de funcionário
- null (usuário sem tipo de funcionário)
Método Auxiliar: ObterEmpresaIdVendedor()
Lógica:
1. Busca contratos ativos do vendedor (FuncionarioContrato)
2. Filtra apenas contratos e empresas ativas
3. Ordena por DataRegistro (ordem crescente)
4. Retorna EmpresaId do primeiro contrato ativo
5. Retorna null se vendedor não tiver empresa
Exceções e Casos Especiais
Vendedor sem Funcionário Configurado
- Sistema exibe mensagem: "Vendedor sem funcionário configurado. Contate o administrador."
- Operação bloqueada até que administrador configure
Vendedor sem Empresa Ativa
- Lista de empresas fica vazia
- Mensagem contextual orienta a contatar administrador
- Impede criação/edição de pedidos
Vendedor sem Clientes na Carteira
- Busca retorna lista vazia
- Mensagem: "Nenhum destinatário encontrado na busca"
- Vendedor pode solicitar que administrador atribua clientes
Usuário sem Tipo de Funcionário
- Tratado como "não-vendedor"
- Sem restrições aplicadas
- Acesso completo (equivalente a administrador)
Arquivos Modificados
Backend (Controllers)
ClienteController.cs: Restrição do campo VendedorIdPedidoController.cs: Restrição de EmpresaId e filtro de busca
Backend (Services)
FuncionarioService.cs: Métodos auxiliares de identificaçãoClienteService.cs: Parâmetro vendedorId na busca
Backend (Repositories)
ClienteRepository.cs: Filtro WHERE por vendedorId
Frontend (Views)
Create.cshtml(Cliente): Campo VendedorId condicionalEdit.cshtml(Cliente): Campo VendedorId condicional_PrincipalPartial.cshtml(Pedido): Campo EmpresaId condicional
Benefícios
✅ Segurança: Impede acesso não autorizado a dados de outros vendedores ✅ Conformidade LGPD: Restringe acesso a dados pessoais de clientes ✅ Integridade: Garante rastreabilidade correta de comissões ✅ Auditoria: Evita manipulação de dados comerciais ✅ UX: Feedback claro sobre restrições e erros
Notas de Implementação
Princípio de Design: Defense in Depth
Todas as restrições seguem o princípio de defesa em profundidade: 1. UI Layer: Campo disabled impede alteração visual 2. Client-Side: JavaScript previne manipulação acidental 3. Server-Side: Validação rigorosa bloqueia tentativas maliciosas 4. Data Layer: Filtros SQL garantem queries seguras
Compatibilidade
- Zero Breaking Changes: Parâmetros opcionais (
vendedorId = null) - Retrocompatibilidade: Métodos existentes funcionam sem alteração
- Extensibilidade: Fácil adicionar novas restrições seguindo o padrão
Última Atualização: 2025-10-23 Responsável: Equipe de Desenvolvimento SGE Status: ✅ Implementado e em Produção