RTC Verificação da Tabela de Anexos

32 views
Skip to first unread message

Reinaldo Alves

unread,
Oct 29, 2025, 5:28:58 PM (7 days ago) Oct 29
to UniNFe
Boa noite,

Fiz uma rotina em C# um parse na página https://www.in.gov.br/en/web/dou/-/lei-complementar-n-214-de-16-de-janeiro-de-2025-607430757 com intuito de verificar a tabela de anexos fornecida pela Unimake.

Não dá para fazer algo 100%. Mas deu para confirmar várias informações e achar erros em outros.

Basicamente verifico cada Anexo e cada NCM. Criei um flag com 3 situações
0 => Não confirmado
1 => Confirmado
2 => Confirmado usando um método fraco

A rotina carece de mais testes e ajustes.

Veja arquivo em Anexo:
------------------------------------
tive que corrigir algumas despadronizações manualmente.

Exemplo:
--------------
var parse = new ParseAnexos();
parse.ParseFileName(@"d:\pagina.html");

Observe que cada ParseAnexo tem a informação de Anexo, lista de NCM e lista NBS. InnerTable permite um teste fraco através do método IndexOfTable.

Código:
------------
public class ParseAnexos : List<ParseAnexo>
    {
        public ParseAnexos()
        {
        }

        public void ParseFileName(string fileName)
        {
            Parse(File.ReadAllText(fileName));
        }

        public void Parse(string text)
        {
            var startAnexoIndex = 0;
            GetTag(text, "<p class=\"anexo\">", out string textAnexo, ref startAnexoIndex);
            while (startAnexoIndex > 0 && textAnexo.StartsWith("ANEXO"))
            {

                var sbDescription = new StringBuilder();
                var startTableIndex = startAnexoIndex;
                GetTag(text, "<table class=\"dou-table\">", out string textTable, ref startTableIndex);

                var startDescriptionIndex = startAnexoIndex;
                GetTag(text, "<p class=\"dou-paragraph\">", out string textDescription, ref startDescriptionIndex);
                while (startDescriptionIndex > 0 && startDescriptionIndex < startTableIndex)
                {
                    textDescription = textDescription.Trim();
                    if (textDescription.Length > 0)
                        sbDescription.Append(textDescription).Append(' ');
                    GetTag(text, "<p class=\"dou-paragraph\">", out textDescription, ref startDescriptionIndex);
                }

                var anexo = new ParseAnexo(textAnexo.Substring(6), sbDescription.ToString().Trim(), textTable);
                this.Add(anexo);

                var isNBS = false;
                var isNCM = false;
                var startRowIndex = 0;
                GetTag(textTable, "<tr>", out string textRow, ref startRowIndex);
                while (startRowIndex > 0)
                {
                    var startCellIndex = 0;
                    GetTag(textRow, "<td rowspan=\"1\" colspan=\"1\">", out string textCell, ref startCellIndex);
                    GetTag(textRow, "<td rowspan=\"1\" colspan=\"1\">", out textCell, ref startCellIndex);
                    GetTag(textRow, "<td rowspan=\"1\" colspan=\"1\">", out textCell, ref startCellIndex);
                    GetTag(textRow, "<p class=\"dou-paragraph\">", out textCell, ref startCellIndex);
                    while (startCellIndex >= 0)
                    {
                        if (textCell == "NBS") isNBS = true;
                        else if (textCell == "NCM/SH") isNCM = true;
                        else if (textCell == "NBS / NCM/SH" || textCell == "NBS/NCM")
                        {
                            //????
                            Console.WriteLine(textCell);
                        }
                        else if (string.IsNullOrEmpty(textCell))
                        {
                            //do nothing
                        }
                        else if (isNBS) anexo.NBS.Add(textCell);
                        else if (isNCM) anexo.NCM.Add(textCell);

                        GetTag(textRow, "<p class=\"dou-paragraph\">", out textCell, ref startCellIndex);
                    }
                    GetTag(textTable, "<tr>", out textRow, ref startRowIndex);
                }

                GetTag(text, "<p class=\"anexo\">", out textAnexo, ref startAnexoIndex);
            }
        }

        public bool IndexOfTable(string anexo, string codiNCM)
        {
            var item = this.Find(x => x.Anexo == anexo);
            return item != null && item.InnerTable.IndexOf(codiNCM) >= 0;
        }

        private static void GetTag(string text, string tag, out string innerText, ref int startIndex)
        {
            innerText = String.Empty;
            if (startIndex >= 0)
            {
                var i = tag.IndexOf(' ');
                var endTagName = i > 0 ? $"</{tag.Substring(1, i - 1)}>" : tag.Insert(1, "/");
                var startTagIndex = text.IndexOf(tag, startIndex);
                if (startTagIndex > 0)
                {
                    startTagIndex = text.IndexOf('>', startTagIndex) + 1;
                    var endTagIndex = text.IndexOf(endTagName, startTagIndex);
                    innerText = startTagIndex > 0 && endTagIndex > 0 ? text.Substring(startTagIndex, endTagIndex - startTagIndex) : "";
                    startIndex = startTagIndex;
                }
                else
                    startIndex = -1;
            }
        }

    }

    public class ParseAnexo
    {
        public ParseAnexo(string anexo, string descricao, string innerTable)
        {
            Anexo = anexo;
            Descricao = descricao;
            InnerTable = innerTable;
            NCM = new List<string>();
            NBS = new List<string>();
        }

        public string Anexo { get; }
        public string Descricao { get; }
        public string InnerTable { get; } //Para tabelas não formatadas em 3 colunas e os códigos estão dentro de um texto
        public List<string> NCM { get; }
        public List<string> NBS { get; }
    }


pagina.html

Wandrey - Unimake

unread,
Oct 29, 2025, 6:00:48 PM (7 days ago) Oct 29
to uni...@googlegroups.com
Tem que considerar que todos os NCMs de um determinado grupo nós já colocamos o anexo para facilitar. Considerou isso?


--
Acompanhe nosso canal exclusivo de notícias e não perca nenhuma nota técnica:
https://whatsapp.com/channel/0029VaCYoen3gvWRRRbKve40
 
Conheça nossos outros fóruns/grupos de apoio:
 
No DISCORD: https://discord.gg/UwFPRxJp3N
No TELEGRAM: https://t.me/joinchat/Lly8_xQkn2NNi4yHN5aPqw
---
You received this message because you are subscribed to the Google Groups "UniNFe" group.
To unsubscribe from this group and stop receiving emails from it, send an email to uninfe+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/uninfe/b0d73373-41fc-40e2-8e32-ea780bddf2b3n%40googlegroups.com.

Reinaldo Alves

unread,
Oct 30, 2025, 9:00:28 AM (7 days ago) Oct 30
to UniNFe
Bom dia,

Depois que você me informou sim.

Encontrei estas referências que merecem um atenção:
"Anexo";"NCM"
"IV";"3926.90.90"
"XII";"9025.1"
"XII";"9025.11"
"XII";"9025.11.1"
"XII";"9025.11.11"
"XII";"9025.11.19"
"XII";"9025.11.9"
"XII";"9025.11.91"
"XII";"9025.11.99"
"XII";"9025.19"
"XII";"9025.19.10"
"XII";"9025.19.90"
"XII";"9025.80.00"
"XII";"9025.90"
"XII";"9025.90.10"
"XII";"9025.90.90"
"XIV";"3002.42"
"XIV";"3004.3"
"XIV";"3004.39"

Código C# corrigido

                if (startTagIndex >= 0)

                {
                    startTagIndex = text.IndexOf('>', startTagIndex) + 1;
                    var endTagIndex = text.IndexOf(endTagName, startTagIndex);
                    innerText = startTagIndex > 0 && endTagIndex > 0 ? text.Substring(startTagIndex, endTagIndex - startTagIndex).Trim() : "";

Wandrey - Unimake

unread,
Oct 30, 2025, 3:21:15 PM (6 days ago) Oct 30
to uni...@googlegroups.com
Boa tarde, Reinaldo.

1) Você tem que levar em consideração também: Tem Anexos que entra um determinado grupo de NCM mas tem exceções, ou seja, alguns NCMs não entram daquele grupo.
2) Também tem a situação que um NCM completo pode estar em um anexo bem como fazer parte de outro anexo por fazer parte de um grupo de NCM, está considerando isso?
3) Por fim, semana que vem vamos fazer mais uma revisão da tabela, temos feito a cada 15 dias em busca de possíveis falhas.

Mas, para que eu possa analisar suas sugestões, seria mais interessante apontar exatamente qual é o problema, assim vamos mais direto, se realmente existir.

Não só nós mas já temos outros devs registrando e avaliando e bem poucos problemas estão aparecendo.

Detalhe:

- Proxima atualização da tabela vamos remover os anexos dos grupos, vai ficar somente nos NCMs com códigos completos já para evitar suporte, já que a ideia é pegar direto no NCM completo.




Reply all
Reply to author
Forward
0 new messages