Pular para conteúdo

Documentação do Método LoadCFOPs() - SGE 2.0

Localização

Arquivo: sge_2_0/NM_2015/Pedido/frm_Pedidos.aspx.cs Linha: 66468

Visão Geral

O método LoadCFOPs() é responsável por carregar dinamicamente os códigos CFOP (Código Fiscal de Operações e Prestações) disponíveis no dropdown ddl_CFOP_3 durante o cadastro de itens de terceiros em um pedido. A seleção dos CFOPs é baseada em múltiplos critérios fiscais e comerciais.

Propósito

Este método implementa a lógica de negócio para determinar quais CFOPs são aplicáveis em uma operação de compra de item de terceiro, considerando: - Regime de compra (Integral ou Beneficiamento) - Situação tributária do item (Com ST ou Sem ST) - Tipo de fornecedor (Comércio, Indústria, Comércio Equiparado à Indústria, ou Indústria e Comércio) - UF do fornecedor (SP ou outros estados)

Dependências

Controles de Interface

  • rbRegimeCompra: RadioButton para seleção do regime (Integral "I" ou Beneficiamento "B")
  • rb_PRDST_3: RadioButton para indicar se o item está em Substituição Tributária ("S" ou "N")
  • rbTipoFornecedor: RadioButton para tipo do fornecedor (índices 0-3)
  • rb_Fornecedor_Ambos: RadioButton usado quando fornecedor é Indústria e Comércio
  • ddl_CFOP_3: DropDownList onde os CFOPs são carregados

Variáveis de Sessão

  • Session["UF_Fornecedor"]: UF do fornecedor selecionado

Métodos Auxiliares

  • AddEmptyItem(ddl, text, value): Adiciona um item ao dropdown na primeira posição

Lógica de Negócio Detalhada

1. Regime Integral (I)

1.1. Item COM Substituição Tributária (S)

1.1.1. Fornecedor: Comércio (índice 0) ou Comércio Equiparado à Indústria (índice 2)

Fornecedor em SP: - 5.405 - Fornecedor Revendedor adquiriu no Regime Integral - 5.403 - Fornecedor Revendedor adquiriu no Regime Beneficiamento

Fornecedor fora de SP: - 6.405 - Fornecedor Revendedor adquiriu no Regime Integral - 6.403 - Fornecedor Revendedor adquiriu no Regime Beneficiamento

1.1.2. Fornecedor: Indústria (índice 1)

Fornecedor em SP: - 5.401 - Fornecedor Fabricante fornecerá no Regime Integral

Fornecedor fora de SP: - 6.401 - Fornecedor Fabricante fornecerá no Regime Integral

1.1.3. Fornecedor: Indústria e Comércio (índice 3)

Depende da seleção em rb_Fornecedor_Ambos:

Se fornecido como Indústria (índice 0): - SP: 5.401 - Fornecedor Fabricante fornecerá no Regime Integral - Fora SP: 6.401 - Fornecedor Fabricante fornecerá no Regime Integral

Se fornecido como Comércio (índice 1): - SP: 5.405 e 5.403 (mesmas descrições acima) - Fora SP: 6.405 e 6.403 (mesmas descrições acima)

1.2. Item SEM Substituição Tributária (N)

1.2.1. Fornecedor: Comércio (índice 0)

Fornecedor em SP: - 5.120 - Venda de mercadoria adquirida ou recebida de terceiros entregue ao destinatário pelo vendedor remetente, em venda à ordem (emitente com atividade do comércio ou indústria e comércio) - 5.102 - Venda de mercadoria adquirida ou recebida de terceiros

Fornecedor fora de SP: - 6.120 - Venda de mercadoria adquirida ou recebida de terceiros entregue ao destinatário pelo vendedor remetente, em venda à ordem - 6.102 - Venda de mercadoria adquirida ou recebida de terceiros

1.2.2. Fornecedor: Indústria (índice 1) ou Comércio Equiparado à Indústria (índice 2)

Fornecedor em SP: - 5.118 - Venda de produção do estabelecimento (emitente com atividade de indústria ou indústria e comércio) - 5.101 - Venda de produção do estabelecimento - 5.103 - Venda de produção do estabelecimento, efetuada fora do estabelecimento

Fornecedor fora de SP: - 6.118 - Venda de produção do estabelecimento (emitente com atividade de indústria ou indústria e comércio) - 6.101 - Venda de produção do estabelecimento - 6.103 - Venda de produção do estabelecimento, efetuada fora do estabelecimento

1.2.3. Fornecedor: Indústria e Comércio (índice 3)

Se fornecido como Indústria (índice 0): - SP: 5.118, 5.101 - Fora SP: 6.118, 6.101

Se fornecido como Comércio (índice 1): - SP: 5.120, 5.102 - Fora SP: 6.120, 6.102

2. Regime Beneficiamento (B)

No regime de beneficiamento, o item sempre está fora da Substituição Tributária.

Fornecedor em SP: - 5.125 - Fornecedor Fabricante fornecerá no Regime Beneficiamento com Industrialização de Terceiros - 5.124 - Fornecedor Fabricante fornecerá no Regime Beneficiamento com Industrialização Própria

Fornecedor fora de SP: - 6.125 - Fornecedor Fabricante fornecerá no Regime Beneficiamento com Industrialização de Terceiros - 6.124 - Fornecedor Fabricante fornecerá no Regime Beneficiamento com Industrialização Própria

Nota: No final, adiciona item "Selecione" com valor "0".

Matriz de Decisão - Resumo

Regime ST Tipo Fornecedor Como Fornece UF SP CFOPs Disponíveis
I S Comércio (0,2) - Sim 5.405, 5.403
I S Comércio (0,2) - Não 6.405, 6.403
I S Indústria (1) - Sim 5.401
I S Indústria (1) - Não 6.401
I S Ambos (3) Indústria Sim 5.401
I S Ambos (3) Indústria Não 6.401
I S Ambos (3) Comércio Sim 5.405, 5.403
I S Ambos (3) Comércio Não 6.405, 6.403
I N Comércio (0) - Sim 5.120, 5.102
I N Comércio (0) - Não 6.120, 6.102
I N Indústria (1,2) - Sim 5.118, 5.101, 5.103
I N Indústria (1,2) - Não 6.118, 6.101, 6.103
I N Ambos (3) Indústria Sim 5.118, 5.101
I N Ambos (3) Indústria Não 6.118, 6.101
I N Ambos (3) Comércio Sim 5.120, 5.102
I N Ambos (3) Comércio Não 6.120, 6.102
B - Qualquer - Sim 5.125, 5.124, Selecione
B - Qualquer - Não 6.125, 6.124, Selecione

Relação com Outros Métodos

O método LoadCFOPs() é chamado em diversos pontos do fluxo de cadastro de item de terceiro:

  1. Linha 13214: Ao carregar dados de um item de terceiro existente
  2. Linha 65653: Em ddl_Liga3_SelectedIndexChanged quando produto é "Outro" (OU)
  3. Linha 66067: Em ddlTipoProduto3_SelectedIndexChanged para recarregar CFOPs
  4. Linha 66371: Em rb_PRDST_3_SelectedIndexChanged quando produto começa com "OU"

Considerações para Migração ao SGE 3.0

1. Arquitetura

No SGE 3.0, esta lógica deve ser migrada para:

Camada de Serviço:

Nelmetais.SGE.Business/Services/Comercial/PedidoItemTerceiroService.cs

Método sugerido:

public IEnumerable<CfopOption> ObterCfopsDisponiveis(
    RegimeCompra regime,
    bool possuiSubstituicaoTributaria,
    TipoFornecedor tipoFornecedor,
    bool fornecedorComoIndustria, // apenas para Indústria e Comércio
    string ufFornecedor
)

2. Estrutura de Dados

Criar classes para representar as opções:

public class CfopOption
{
    public string Codigo { get; set; }
    public string Descricao { get; set; }
}

public enum RegimeCompra
{
    Integral = 'I',
    Beneficiamento = 'B'
}

public enum TipoFornecedor
{
    Comercio = 0,
    Industria = 1,
    ComercioEquiparadoIndustria = 2,
    IndustriaEComercio = 3
}

3. Validações

Implementar validações com FluentValidation para garantir: - Regime de compra válido - Tipo de fornecedor válido - UF do fornecedor preenchida - Coerência entre tipo de fornecedor e seleção "Como Fornece"

4. Tabela de Banco de Dados (Opcional)

Considerar criar uma tabela CfopRegras para tornar as regras configuráveis:

CREATE TABLE CfopRegras (
    Id INT PRIMARY KEY IDENTITY,
    RegimeCompra CHAR(1) NOT NULL,
    PossuiST BIT,
    TipoFornecedor INT NOT NULL,
    ComoFornece VARCHAR(10), -- 'Industria' ou 'Comercio' (apenas para tipo 3)
    UfInterna BIT NOT NULL, -- true se SP, false se outros estados
    CodigoCfop VARCHAR(4) NOT NULL,
    DescricaoCfop VARCHAR(500) NOT NULL,
    Ordem INT NOT NULL
);

5. Componente Frontend

No SGE 3.0 (MVC):

ViewModel:

public class PedidoItemTerceiroViewModel
{
    public RegimeCompra RegimeCompra { get; set; }
    public bool PossuiSubstituicaoTributaria { get; set; }
    public TipoFornecedor TipoFornecedor { get; set; }
    public bool FornecedorComoIndustria { get; set; }
    public string UfFornecedor { get; set; }

    // Lista de CFOPs disponíveis
    public IEnumerable<SelectListItem> CfopsDisponiveis { get; set; }
    public string CfopSelecionado { get; set; }
}

Controller:

[HttpGet]
public JsonResult ObterCfops(
    char regimeCompra,
    bool possuiST,
    int tipoFornecedor,
    bool? comoIndustria,
    string ufFornecedor)
{
    var cfops = _pedidoItemTerceiroService.ObterCfopsDisponiveis(
        (RegimeCompra)regimeCompra,
        possuiST,
        (TipoFornecedor)tipoFornecedor,
        comoIndustria ?? false,
        ufFornecedor
    );

    return Json(cfops, JsonRequestBehavior.AllowGet);
}

JavaScript:

function carregarCfops() {
    var regimeCompra = $('input[name="RegimeCompra"]:checked').val();
    var possuiST = $('input[name="PossuiST"]:checked').val() === 'S';
    var tipoFornecedor = $('input[name="TipoFornecedor"]:checked').val();
    var comoIndustria = $('input[name="ComoFornece"]:checked').val() === 'I';
    var ufFornecedor = $('#UfFornecedor').val();

    $.ajax({
        url: '/Comercial/Pedido/ObterCfops',
        type: 'GET',
        data: {
            regimeCompra: regimeCompra,
            possuiST: possuiST,
            tipoFornecedor: tipoFornecedor,
            comoIndustria: comoIndustria,
            ufFornecedor: ufFornecedor
        },
        success: function(cfops) {
            var $select = $('#CfopSelecionado');
            $select.empty();
            $select.append('<option value="">Selecione</option>');

            $.each(cfops, function(i, cfop) {
                $select.append(
                    $('<option></option>')
                        .val(cfop.Codigo)
                        .text(cfop.Codigo + ' - ' + cfop.Descricao)
                );
            });
        }
    });
}

// Disparar ao mudar qualquer campo relevante
$('input[name="RegimeCompra"], input[name="PossuiST"], input[name="TipoFornecedor"], input[name="ComoFornece"]')
    .on('change', carregarCfops);

$('#UfFornecedor').on('change', carregarCfops);

6. Testes Unitários

Criar testes para cobrir todos os cenários da matriz de decisão:

[TestClass]
public class PedidoItemTerceiroServiceTests
{
    [TestMethod]
    public void ObterCfops_RegimeIntegral_ComST_ComercioSP_DeveRetornar5405E5403()
    {
        // Arrange
        var service = new PedidoItemTerceiroService();

        // Act
        var cfops = service.ObterCfopsDisponiveis(
            RegimeCompra.Integral,
            possuiSubstituicaoTributaria: true,
            TipoFornecedor.Comercio,
            fornecedorComoIndustria: false,
            "SP"
        );

        // Assert
        Assert.AreEqual(2, cfops.Count());
        Assert.IsTrue(cfops.Any(c => c.Codigo == "5405"));
        Assert.IsTrue(cfops.Any(c => c.Codigo == "5403"));
    }

    // ... outros testes para cada cenário
}

7. Pontos de Atenção

  1. Padrão 5xxx vs 6xxx: Os CFOPs começam com 5 para operações internas (dentro do estado) e 6 para operações interestaduais. No código SGE 2.0, a verificação é se UF é "SP", mas idealmente deveria comparar UF do fornecedor com UF da empresa compradora.

  2. Índices do RadioButton: O código usa índices (0, 1, 2, 3) para identificar tipos. No SGE 3.0, usar enums é mais seguro e legível.

  3. Item "Selecione": Apenas o regime Beneficiamento adiciona explicitamente um item "Selecione" ao final. Verificar se isso é intencional ou se deveria ser adicionado em todos os casos.

  4. Validação de Campos: Antes de chamar LoadCFOPs(), garantir que todos os campos necessários estejam preenchidos (fornecedor, regime, tipo, etc.).

  5. Relação com CST: O CFOP selecionado influencia quais CSTs são válidos (ver método ddlTipoProduto3_SelectedIndexChanged linhas 66103-66167). Essa relação também deve ser implementada no SGE 3.0.

Referências no SGE 2.0

  • Método AddEmptyItem: Linha 59139
  • Método LoadCST: Linha 66615 (relacionado, carrega CSTs baseado em CFOP e regime)
  • Definição de CST por CFOP: Linhas 66103-66167

Status da Migração

  • [ ] Criar enums e classes de domínio
  • [ ] Implementar serviço na camada Business
  • [ ] Criar testes unitários
  • [ ] Implementar endpoint no Controller
  • [ ] Implementar JavaScript no frontend
  • [ ] Integrar com formulário de item de terceiro
  • [ ] Validar com equipe fiscal
  • [ ] Testar todos os cenários
  • [ ] Documentar API

Autor da Documentação

Documentado para auxiliar na migração do SGE 2.0 para SGE 3.0.

Data: 2025-11-13