Skip to Content
SAP Electronic Invoicing for Brazil (SAP Nota Fiscal Eletronica)

PI/NF-e: XPath como acelerador para regras de receiver determination

Tags:

Olá, pessoal,

Talvez não seja novidade para todos, mas acredito que o post a seguir pode sim ajudar algumas pessoas.

Recentemente estive junto com o Former Member em um projeto fazendo a implementação do PI para atender as interfaces de NF-e. O ambiente já estava totalmente configurado para 4 estados, mas o requisito é que adicionalmente todas as SEFAZ e todos os serviços contemplados pelo SAP NFE fossem cobertos.

Iniciamos o trabalho de planejamento das atividades, e estimamos grosseiramente o seguinte:

25 novos parties (1 para cada SEFAZ + Ambiente Nacional + SVCs)

x

2 business services (homologação e produção)

x

6 canais de comunicação

=

~ 300 regras unívocas de roteamento para receiver determination

Acrescentando-se os mapping especiais de Bahia para SKIPR e SRVSC + o ajuste de outros objetos do cliente, chegamos a um número aproximado de 315 objetos a serem editados. Estimamos algo em torno de 15-20 minutos por objeto (considerando correções, eventual retrabalho, erros na ativação, etc), chegando ao tempo aproximado de ~80 horas de configuração ou ~ 2 semanas.

(Isso sem contar o tempo de documentação e assumindo que o ambiente de DEV estaria disponível e responsivo o tempo todo - pausa para sorriso sarcástico ).

Mas daí, olhando com mais atenção, surgiu a ideia de tentar melhorar isso, tanto para ganhar tempo quanto para facilitar a manutenção. Abaixo o passo-a-passo do que construímos:

1° agregar parties


A primeira medida que tomamos foi agregar parties o máximo possível. Como? Criando apenas 1 cadeia de party/service/cc para SVRS e outra para SVAN. Já vi muitas empresas (grandes, pequenas, médias, mas muitas) criando 1 cadeia para cada estado, mesmo aqueles atendidos pelas SEFAZ Virtuais.

O argumento que ouvi para isso foi: "caso a SEFAZ xpto decida sair do serviço virtual, a regra de roteamento já estará prevista e não precisaremos de um consultor PI para reconfigurar - basta mudar o endpoint".

Ok, o argumento é válido (apesar disso não ser muito frequente), mas vocês verão abaixo que isso deixa de ser um problema quando definirmos o condicional de roteamendo no receiver de maneira dinâmica com o XPath.

Primeiro ganho: Fazendo isso, com 2 cadeias já servimos 16 estados. Sobram os 11 estados com web service próprio + SVs + AN + SVC. Com essa simples medida caímos de 29 para 16 cadeias de objetos.


Segundo ganho: Outro ganho é que como o endpoint das SEFAZ Virtuais é um só, não é necessário ficar ajustando "n" objetos quando muda a URL do web service.

2° Incluir o <cUF> no nome do party

Se você ler rápido, vai parecer uma idea obcena. Mas não é ( ). A ideia aqui é que o nome do party contenha os 2 dígitos que identificam o estado. Aqui fizemos assim:


"NFE10_SEFAZ_<cUF>", o que nos deixou com os seguintes objetos:


PartyEstado
NFE10_SEFAZ_13AM
NFE10_SEFAZ_29BA
NFE10_SEFAZ_23CE
NFE10_SEFAZ_52GO
NFE10_SEFAZ_31MG
NFE10_SEFAZ_50MS
NFE10_SEFAZ_51MT
NFE10_SEFAZ_26PE
NFE10_SEFAZ_41PR
NFE10_SEFAZ_43RS
NFE10_SEFAZ_35SP
NFE10_SEFAZ_SVRSSVRS
NFE10_SEFAZ_SVANSVAN
NFE10_SEFAZ_SVC_RSSVC-RS
NFE10_SEFAZ_SVC_ANSVC-AN
NFE10_SEFAZ_ANAN


Ok... mas pra quê isso?


Terceiro ganho: Fazendo isso, para as SEFAZ próprias, poderemos determinar o party dinamicamente a partir do conteúdo do payload, utilizando uma expressão do XPath. Veremos em seguida.


3° Mapeamento de condições para expressões do XPath


Aqui é a parte que mais queimamos neurônio. O XPath, como a maioria já deve saber, nos permite manusear os condicionais de roteamento de maneira menos "engessaga" se comparada às expressões básicas que a interface do integration builder nos oferece.


Para entender melhor como isso funciona, li os seguintes conteúdos:


Customise your 'XPATH' Expressions in Receiver Determination (dica preciosa da Carolina Garcia, que não está no SCN, mas é feríssima do PI)

Xpath Condition in Receiver Determination - Process Integration - SCN Wiki

Using the Condition Editor - Integration Directory - SAP Library

(Também contei com a ajuda do jedi @Flavio Lazanha para refinar o entendimento)

Muito bem, entendida a tecnologia, partimos para a criação dos condicionais. Como tudo gira em torno de 3 campos-chave, todas as regras foram criadas com base neles:

- cUF

- tpAmb

- tpEmis

E como a grande variedade de possibilidades está no cUF, o condicional com expressões do XPath foi feito em cima deste campo, usando 2 expressões básicas.  :

1) Validação da cUF desejada

      /p1:<tipo de msg>[(p1:cUF = 'xx' or p1:cUF = 'yy' (...) or p1:cUF = 'zz')]

2) Eliminação das cUF indesejadas

     /p1:<tipo de msg>[(not(p1:cUF = 'nn' or p1:cUF = 'mm' (...) or p1:cUF = 'jj'))]

Para não ocorrer múltiplos receivers, a "pergunta pro PI" tem que ter apenas 1 resposta possível. A resposta tem que dizer qual é a cUF em questão, univocamente. Para chegar nisso, então, montamos 6 expressões lógicas para mapearmos todas as possibilidades:

PerguntaExpressão XPath
Validar SEFAZ própria ("=Prop")/p1:<tipo de msg>[(p1:cUF = '13' or p1:cUF = '29' or p1:cUF = '23' or p1:cUF = '52' or p1:cUF = '31' or p1:cUF = '50' or p1:cUF = '51' or p1:cUF = '26' or p1:cUF = '41' or p1:cUF = '43' or p1:cUF = '35')]

Excluir SEFAZ própria

("<>Prop")

/p1:<tipo de msg>[(not(p1:cUF = '13' or p1:cUF = '29' or p1:cUF = '23' or p1:cUF = '52' or p1:cUF = '31' or p1:cUF = '50' or p1:cUF = '51' or p1:cUF = '26' or p1:cUF = '41' or p1:cUF = '43' or p1:cUF = '35'))]

Validar SVRS

("=SVRS")

/p1:NfeAutorizacaoLote[(p1:cUF = '13' or p1:cUF = '29' or p1:cUF = '23' or p1:cUF = '52' or p1:cUF = '31' or p1:cUF = '50' or p1:cUF = '51' or p1:cUF = '26' or p1:cUF = '41' or p1:cUF = '43' or p1:cUF = '35')]

Excluir SVRS

("<>SVRS")

/p1:<tipo de msg>[(not(p1:cUF = '12' or p1:cUF = '27' or p1:cUF = '16' or p1:cUF = '53' or p1:cUF = '25' or p1:cUF = '33' or p1:cUF = '24' or p1:cUF = '11' or p1:cUF = '14' or p1:cUF = '42' or p1:cUF = '28' or p1:cUF = '32' or p1:cUF = '17'))]

Validar SVAN

("=SVAN")

/p1:<tipo de msg>[(p1:cUF = '21' or p1:cUF = '15' or p1:cUF = '22')]

Excluir SVAN

("<>SVAN")

/p1:<tipo de msg>[(not(p1:cUF = '21' or p1:cUF = '15' or p1:cUF = '22'))]

Feito isso, passamos a configurar as regras de roteamento, que basicamente se concentraram em 3 grupos (sem contar SVCs e AN):

RegraCondições XPath
Enviar para SEFAZ PrópriacUF = Prop AND <>SVRS AND <>SVAN
Enviar para SVRScUF = SVRS AND <>SVAN AND <> Prop
Enviar para SVANcUF = SVAN AND <>SVRS AND <> Prop

O tpEmis e o tpAmb também devem ser considerados, mas sem expressões do XPath.

4° Implementação


A implementação é essencialmente uma atividade operacional. Só é preciso atenção para não errar na expressão lógica em cada caso, e lembrar de colocar as regras de tpEmis e tpAmb.

Abaixo, vou colocar o passo-a-passo de exemplo do receiver determination para estados com SEFAZ própria do cenário BATCH sem zip:

Importante: Antes de seguir adiante, tirei um backup da modelagem atual. Recomendo que façam o mesmo, just in case.

1) No editor de condições, escolha o operador lógico "EX"

2) Selecione o modo de entrada "XPath" e insira a expressão inteira lá

Exemplo: expressão para "= Prop".

3) Repita o processo para cada uma das expressões deste receiver, conforme a tabelinha anterior:

Exemplo: no caso, "= Prop AND <>SVRS AND <>SVAN":

4) Para determinar o party de destino da mensagem, insira uma expressão XPath de concatenação composto pela literal do nome + <cUF>:

    concat('NFE10_SEFAZ_',/p1:<tipo de msg>/p1:cUF)

Quarto Ganho: com isso, basta 1 linha do receiver para determinar o roteamento de todas os estados com SEFAZ própria.

Nota: Para SVAN e SVRS não é necessário fazer o XPath pois a cUF não compõe o nome do party.


5) O resultado final será o seguinte:

Com 10 regras de roteamento cobrimos todas as possibilidades.

6) Comparativo antes e depois, por exemplo, para o cenário de BATSR:


Sexto Ganho: 10 objetos por cenário, ao invés de 29.



5° O Excel com o acelerador


Como comentei, a parte mais trabalhosa foi o passo 3 - chegar até as expressões unívocas de cada cenário.


Com o acelerador em mãos (link a seguir), o passo 4 é apenas repetição operacional e centenas de cliques.


Para quem se interessar em aplicar com esse modelo, o acelerador completo, com todas as regras e condicionais já mapeados, pode ser baixado aqui: Download NFE PI RecDet XPath



Considerações finais


Nos testes que efetuamos, não foram observadas alterações na performance. A etapa do pipeline de receiver determination continuou levando milisegundos.


Evidente que seguimos acompanhando, e se constatarmos que isso é um problema, é sempre bom ter um tpz com o modelo anterior de backup. Por isso, a recomendação lá em cima de tirar um snapshot da modelagem anterior.

A estimativa é que com essa abordagem, ao invés de ~315 atividades de manutenção de objetos, caiamos para algo em torno de 160, ou seja, uma economia de por volta de ~40h de trabalho. O que nos leva ao...:

Grande ganho: economia de tempo, recurso e dinheiro.

Quem se aventurar, dê um feedback, será muito bem-vindo!!

Abraços,

Eduardo Rubia