Pular para conteúdo

Fluxo de Pedido e Análise

Este documento descreve a máquina de estados do pedido e o processo de análise necessário para liberação ao faturamento.

Tipos de Pedido (Cotação vs Pedido)

Antes de entender a máquina de estados, é importante diferenciar os tipos de pedido:

TipoPedidoId Nome Descrição
1 Cotação Orçamento/proposta comercial, ainda não confirmado
2 Pedido Venda confirmada, pronta para finalização e faturamento

Enum: TipoPedidoEnum

public enum TipoPedidoEnum
{
    Cotacao = 1,
    Pedido = 2
}

Localização: src/Nelmetais.SGE.Business/Enums/Comercial/TipoPedidoEnum.cs

Fluxo Cotação → Pedido → Análise

Quando uma Cotação é finalizada, ela passa por duas etapas:

┌──────────────────────────────────────────────────────────────────────────────┐
│                     FLUXO COMPLETO: COTAÇÃO → PEDIDO → ANÁLISE               │
└──────────────────────────────────────────────────────────────────────────────┘

  TIPO: COTAÇÃO (1)                    TIPO: PEDIDO (2)
  ┌─────────────┐                      ┌─────────────┐
  │   COTAÇÃO   │                      │   PEDIDO    │
  │   ABERTA    │ ─── Finalizar ────>  │   ABERTO    │
  │             │     (1º clique)      │             │
  └─────────────┘                      └──────┬──────┘
                                              │ Finalizar
                                              │ (2º clique)
                                       ┌─────────────┐
                                       │ EM ANÁLISE  │
                                       │     (2)     │
                                       └──────┬──────┘
                                              │ Análises aprovadas
                                       ┌─────────────┐     ┌───────────┐
                                       │  A FATURAR  │ ──> │  FECHADO  │
                                       │     (3)     │     │    (4)    │
                                       └─────────────┘     └───────────┘

Comportamento do botão "Finalizar":

Tipo Atual Situação Ação do "Finalizar" Resultado
Cotação (1) Aberto FinalizarCotacao() Converte para Pedido (2), mantém Aberto
Pedido (2) Aberto FinalizarPedido() Cria análises, muda para Em Análise
Pedido (2) Em Análise FinalizarPedido() Recria análises se necessário

Código responsável (PedidoService.Finalizar):

public async Task Finalizar(Pedido pedido)
{
    switch (pedido.TipoPedidoId)
    {
        case (int)TipoPedidoEnum.Cotacao:
            await FinalizarCotacao(pedido);  // Converte para Pedido
            break;
        case (int)TipoPedidoEnum.Pedido:
            await FinalizarPedido(pedido);   // Cria análises
            break;
    }
}

Máquina de Estados do Pedido

┌─────────────────────────────────────────────────────────────────────────────┐
│                           MÁQUINA DE ESTADOS                                 │
└─────────────────────────────────────────────────────────────────────────────┘

    ┌─────────┐                      ┌────────────┐
    │ ABERTO  │ ──── Finalizar ────> │ EM ANÁLISE │
    │   (1)   │      Pedido          │    (2)     │
    └─────────┘                      └─────┬──────┘
                                           │ Todas as análises
                                           │ aprovadas?
                                     ┌─────▼──────┐     ┌─────────┐
                                     │ A FATURAR  │ --> │ FECHADO │
                                     │    (3)     │     │   (4)   │
                                     └────────────┘     └─────────┘

Estados do Pedido

ID Estado Descrição
1 Aberto Pedido em edição/criação
2 Em Análise Pedido finalizado, aguardando aprovação das análises
3 A Faturar Todas as análises aprovadas, pronto para faturamento
4 Fechado Pedido faturado/concluído

Enum: TipoSituacaoPedidoEnum

public enum TipoSituacaoPedidoEnum
{
    Aberto = 1,
    EmAnalise = 2,
    AFaturar = 3,
    Fechado = 4
}

Localização: src/Nelmetais.SGE.Business/Enums/Comercial/TipoSituacaoPedidoEnum.cs


Transições de Estado

1. Aberto → Em Análise (Finalizar Pedido)

Ação do usuário: Clicar em "Finalizar Pedido"

Método responsável: PedidoService.FinalizarPedido()

O que acontece:

  1. Validações do pedido são executadas
  2. O método GerarPedidoAnalise() cria análises pendentes baseadas em regras de negócio
  3. O status do pedido muda para "Em Análise"

Análises criadas automaticamente:

Tipo ID Quando é criada
Crédito para Venda 1 Se tem forma de pagamento configurada
Disponibilidade de Estoque 2 Se natureza de operação é do tipo Saída
Endereço do Destinatário 3 Se o endereço é novo (não cadastrado)
Pessoa Jurídica sem CNAE 5 Se destinatário PJ não tem CNAE
Mercadoria com Estoque Insuficiente 6 Se estoque é insuficiente para algum item
Dados do Destinatário Inválidos 7 Se CPF/CNPJ, Contribuinte ou Regime Tributário faltando
Devolução de Venda 8 Se é uma devolução de venda

2. Em Análise → A Faturar (Aprovar Análises)

Ação do usuário: Aprovar todas as análises pendentes

Método responsável: PedidoService.AnalisarSituacao()

Condição para transição:

var analises = await _pedidoAnaliseRepository.Find(pa =>
    pa.PedidoId == pedido.Id &&
    pa.TipoSituacaoPedidoAnaliseId != (int)TipoSituacaoPedidoAnaliseEnum.Aprovado);

if (analises.Any())  // Se existir qualquer análise NÃO aprovada
    return;          // Não muda o status

pedido.TipoSituacaoId = (int)TipoSituacaoPedidoEnum.AFaturar;

Importante: A transição é automática quando a última análise é aprovada.

3. A Faturar → Fechado

Ação: Emissão de NF-e (faturamento)


Estados da Análise

Cada análise criada possui seu próprio ciclo de vida:

ID Estado Descrição
1 Não Analisado Análise pendente (estado inicial)
2 Em Análise Análise em andamento
3 Aprovado Análise aprovada
4 Negado Análise negada

Enum: TipoSituacaoPedidoAnaliseEnum

public enum TipoSituacaoPedidoAnaliseEnum
{
    NaoAnalisado = 1,
    EmAnalise = 2,
    Aprovado = 3,
    Negado = 4
}

Localização: src/Nelmetais.SGE.Business/Enums/Comercial/TipoSituacaoPedidoAnaliseEnum.cs


Tipos de Análise

Enum: TipoPedidoAnaliseEnum

public enum TipoPedidoAnaliseEnum
{
    CreditoVenda = 1,
    DisponibilidadeEstoque = 2,
    EnderecoDestinatario = 3,
    OrdemServicoItem = 4,
    PessoaJuridicaSemCNAE = 5,
    MercadoriaEstoqueInsuficiente = 6,
    DadosDestinatarioInvalidos = 7,
    DevolucaoVenda = 8,
}

Localização: src/Nelmetais.SGE.Business/Enums/Comercial/TipoPedidoAnaliseEnum.cs


Como Acessar a Tela de Análise

Via Menu

Administrativo → Gerencial → Autorizações → Comercial → Análise de Pedido

Via URL Direta

Tela URL
Lista de Análises /Comercial/lista-pedido-analise
Análise de Crédito para Venda /Comercial/analisar-pedido-credito-venda/{id}
Análise de Disponibilidade de Estoque /Comercial/analisar-pedido-disponibilidade-estoque/{id}
Análise de Endereço do Destinatário /Comercial/analisar-pedido-endereco-destinatario/{id}
Análise de Dados Destinatário Inválidos /Comercial/analisar-pedido-dados-destinatario-invalidos/{id}
Análise de Mercadoria com Estoque Insuficiente /Comercial/analisar-pedido-mercadoria-estoque-insuficiente/{id}
Análise de Pessoa Jurídica sem CNAE /Comercial/analisar-pedido-pessoa-juridica-sem-cnae/{id}
Análise de Devolução de Venda /Comercial/analisar-pedido-devolucao-venda/{id}
Análise de Ordem de Serviço do Item /Comercial/analisar-pedido-ordem-servico-item/{id}

Permissões Necessárias

Para acessar a funcionalidade de Análise de Pedido, o usuário precisa das seguintes permissões:

Permissão Enum Descrição
PedidoAnalise (58) + Listar (0) Acesso à lista de análises
PedidoAnalise (58) + Detalhar (1) Visualizar detalhes da análise
PedidoAnalise (58) + AnaliseCreditoVenda (20) Aprovar/Negar crédito para venda
PedidoAnalise (58) + AnaliseDisponibilidadeEstoque (21) Aprovar/Negar disponibilidade de estoque
PedidoAnalise (58) + AnaliseEnderecoDestinatario (22) Aprovar/Negar endereço do destinatário
PedidoAnalise (58) + AnaliseDadosDestinatarioInvalidos (28) Aprovar/Negar dados do destinatário
PedidoAnalise (58) + AnaliseMercadoriaEstoqueInsuficiente (29) Aprovar/Negar mercadoria com estoque insuficiente
PedidoAnalise (58) + AnalisePessoaJuridicaSemCnae (30) Aprovar/Negar PJ sem CNAE
PedidoAnalise (58) + AnaliseDevolucaoVenda (31) Aprovar/Negar devolução de venda
PedidoAnalise (58) + AnaliseOrdemServicoItem (38) Aprovar/Negar ordem de serviço do item

Fluxo de Aprovação Passo a Passo

  1. Criar/Editar pedido e adicionar itens
  2. Clicar em "Finalizar Pedido"
  3. Sistema cria análises pendentes automaticamente
  4. Status muda de "Aberto" para "Em Análise"
  5. Acessar a tela de Análise de Pedido
  6. Menu: Administrativo → Gerencial → Autorizações → Comercial → Análise de Pedido
  7. Filtrar pelo pedido (opcional)
  8. Para cada análise pendente:
  9. Clicar na análise
  10. Revisar informações
  11. Selecionar status "Aprovado" ou "Negado"
  12. Adicionar observação (opcional)
  13. Salvar
  14. Quando a última análise for aprovada:
  15. Sistema automaticamente muda o status do pedido para "A Faturar"

Arquivos Relacionados

Arquivo Descrição
src/Nelmetais.SGE.Business/Services/Comercial/PedidoService.cs Lógica de finalização e análise de situação
src/Nelmetais.SGE.Business/Services/Comercial/PedidoAnaliseService.cs Serviço de análise de pedido
src/Nelmetais.SGE.WebApp/Areas/Comercial/Controllers/PedidoAnaliseController.cs Controller das telas de análise
src/Nelmetais.SGE.WebApp/Areas/Comercial/Views/PedidoAnalise/ Views das telas de análise
src/Nelmetais.SGE.Business/Enums/Comercial/TipoSituacaoPedidoEnum.cs Enum de estados do pedido
src/Nelmetais.SGE.Business/Enums/Comercial/TipoSituacaoPedidoAnaliseEnum.cs Enum de estados da análise
src/Nelmetais.SGE.Business/Enums/Comercial/TipoPedidoAnaliseEnum.cs Enum de tipos de análise

Consultas SQL Úteis

Verificar análises pendentes de um pedido

SELECT
    pa."Id",
    pa."PedidoId",
    pa."TipoPedidoAnaliseId",
    pa."TipoSituacaoPedidoAnaliseId",
    pa."ObservacaoTipoPedidoAnalise",
    pa."CriadoEm"
FROM "PedidoAnalise" pa
WHERE pa."PedidoId" = {pedido_id};

Verificar status de um pedido

SELECT
    "Id",
    "TipoPedidoId",
    "TipoSituacaoId",
    "Ativo"
FROM "Pedido"
WHERE "Id" = {pedido_id};

Listar pedidos em análise

SELECT
    p."Id",
    p."TipoSituacaoId",
    COUNT(pa."Id") as "TotalAnalises",
    COUNT(CASE WHEN pa."TipoSituacaoPedidoAnaliseId" = 3 THEN 1 END) as "Aprovadas"
FROM "Pedido" p
LEFT JOIN "PedidoAnalise" pa ON pa."PedidoId" = p."Id"
WHERE p."TipoSituacaoId" = 2  -- Em Análise
GROUP BY p."Id", p."TipoSituacaoId";