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ércioddl_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:
- Linha 13214: Ao carregar dados de um item de terceiro existente
- Linha 65653: Em
ddl_Liga3_SelectedIndexChangedquando produto é "Outro" (OU) - Linha 66067: Em
ddlTipoProduto3_SelectedIndexChangedpara recarregar CFOPs - Linha 66371: Em
rb_PRDST_3_SelectedIndexChangedquando 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:
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
-
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.
-
Í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.
-
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.
-
Validação de Campos: Antes de chamar
LoadCFOPs(), garantir que todos os campos necessários estejam preenchidos (fornecedor, regime, tipo, etc.). -
Relação com CST: O CFOP selecionado influencia quais CSTs são válidos (ver método
ddlTipoProduto3_SelectedIndexChangedlinhas 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