C# - EFD Reinf v1_04_00 - How to instantiate and fill in all Events properties?

Asked

Viewed 337 times

0

After my question answered here:

EFD-Reinf - Invalid batch version. Version 1.04.00 must be used

And in the question: REINF - Invalid Signature

It was clarified that I need to serialize xml. Through XSD, I managed the classes in c#, also using the @Pedro Gaspar : XSD.EXE Generate classes in C# - EFD Reinf v1_04_00

So far OK, I arrive at instantiating the generated class(s) (s): (Here in case the R-1000 record):

 var cadastro = new Reinf();

 cadastro.evtInfoContri.id = "1000";
 cadastro.evtInfoContri.ideEvento.tpAmb = 2;
 cadastro.evtInfoContri.ideEvento.procEmi = 1;
 cadastro.evtInfoContri.ideEvento.verProc = "1";

My first idea was to instantiate the Root Element of the Event, in this case the Reinf and fill in the following properties of the elements "children", one by one.

Looking at the class generated by XSD.EXE, I saw that it generated a class for each "group" element of the event:

public partial class Reinf {

    /// <remarks/>
    public ReinfEvtInfoContri evtInfoContri;
}

...

public partial class ReinfEvtInfoContri {

    /// <remarks/>
    public ReinfEvtInfoContriIdeEvento ideEvento;

    /// <remarks/>
    public ReinfEvtInfoContriIdeContri ideContri;

    /// <remarks/>
    public ReinfEvtInfoContriInfoContri infoContri;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="ID")]
    public string id;
}

...

public partial class ReinfEvtInfoContriIdeEvento {

    /// <remarks/>
    public uint tpAmb;

    /// <remarks/>
    public uint procEmi;

    /// <remarks/>
    public string verProc;
}

...

My question is:

1: I managed the class correctly by XSD.EXE?

2: If so, do I need to instantiate each class corresponding to the group to fill in the properties? Because when trying to fill the properties of the event, it returns error to me (by not having instantiated):

Erro ao preencher propriedades

3: How to serializo the full event ? since the full event is composed of several classes. I tried so and it only generates the first block:

    XmlSerializer ArquivoSerializer = new XmlSerializer(typeof(Reinf));
    using (FileStream ArquivoStream = new FileStream(@"C:\REINF\ZZZ.XML", FileMode.CreateNew))
    {
        using (XmlWriter ArquivoWriter = XmlWriter.Create(ArquivoStream))
        {
            //ArquivoSerializer.Serialize(ArquivoWriter,  pSerializableObject);

            ArquivoSerializer.Serialize(ArquivoWriter, cadastro);

        }
        //return new FileInfo(ArquivoStream.Name);
    }

1 answer

1


Answering the questions:

1: I managed the class correctly by XSD.EXE?

Yes, that’s right. Each group of information needs to be a new class. And in case the group may occur more than once, you will have an array of objects of that class.

2: If yes, I need to instantiate each class corresponding to the group to fill the properties?

Yes, you do. Any property of the "custom class" type, that is, reference a new information group within the event structure, will come with value null and you will need to explicitly create an object to "play on this property".

Tip: Place each generated event class within a specific namespace, because they all have the root element with the same name, Reinf, and when you add the class of the second event will already give conflict, if they are not in separate namespaces. You can put this first class in the namespace R1000, for example:

namespace R1000 {
    using System.Xml.Serialization;
    
    public partial class Reinf {
        public ReinfEvtInfoContri evtInfoContri;
    }

    // [...]
}

And the creation of the object of the R-1000 event would look something like this:

// Elemento raiz EFD-Reinf.
var r1000 = new R1000.Reinf();

// Evento de informações do Contribuinte.
r1000.evtInfoContri = new R1000.ReinfEvtInfoContri();
// Identificação única do evento.
// Regra de validação: REGRA_VALIDA_ID_EVENTO
r1000.evtInfoContri.id = "ID2333901700001892014020213424700001";

// Informações de Identificação do Evento
r1000.evtInfoContri.ideEvento = new R1000.ReinfEvtInfoContriIdeEvento();
r1000.evtInfoContri.ideEvento.tpAmb = 2;
r1000.evtInfoContri.ideEvento.procEmi = 1;
r1000.evtInfoContri.ideEvento.verProc = "1";

// Informações de identificação do contribuinte
r1000.evtInfoContri.ideContri = new R1000.ReinfEvtInfoContriIdeContri();
r1000.evtInfoContri.ideContri.tpInsc = 1;
r1000.evtInfoContri.ideContri.nrInsc = "";

// Identificação da operação (inclusão, alteração ou exclusão) e das
// respectivas informações do Contribuinte.
r1000.evtInfoContri.infoContri = new R1000.ReinfEvtInfoContriInfoContri();
// Inclusão de novas informações
var inclusao = new R1000.ReinfEvtInfoContriInfoContriInclusao();
// Essa propriedade receberá um objeto de inclusão,
// mas poderia ser alteração ou exclusão também.
r1000.evtInfoContri.infoContri.Item = inclusao

// Período de validade das informações incluídas
inclusao.idePeriodo = new R1000.ReinfEvtInfoContriInfoContriInclusaoIdePeriodo();
inclusao.idePeriodo.iniValid = "2019-01";
//inclusao.idePeriodo.fimValid = "";

// Informações do Contribuinte
inclusao.infoCadastro = new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastro();
inclusao.infoCadastro.classTrib = "";
inclusao.infoCadastro.indEscrituracao = 0;
inclusao.infoCadastro.indDesoneracao = 0;
inclusao.infoCadastro.indAcordoIsenMulta = 0;
inclusao.infoCadastro.indSitPJ = 0;
// A ferramenta XSD.exe cria esses campos '{nomeDoCampo}Specified'
// no caso de campos opcionais, e aí você deve informar manualmente
// se o campo está sendo informado ou não.
inclusao.infoCadastro.indSitPJSpecified = true;

// Informações de contato
inclusao.infoCadastro.contato = new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastroContato();
inclusao.infoCadastro.contato.nmCtt = "";
inclusao.infoCadastro.contato.cpfCtt = "";
inclusao.infoCadastro.contato.foneFixo = "";
inclusao.infoCadastro.contato.foneCel = "";
inclusao.infoCadastro.contato.email = "";

// Informações da(s) empresa(s) desenvolvedora(s) da(s) aplicação(ões) que
// gera(m) os arquivos transmitidos para o ambiente nacional da EFD-Reinf.
//-------------------------------------------------------------------------
// Essa propriedade é um array, porque esse grupo pode ocorrer de 0 a 99 vezes.
inclusao.infoCadastro.softHouse = new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastroSoftHouse[]
   { new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastroSoftHouse()
      {
        cnpjSoftHouse = "";
        nmRazao = "";
        nmCont = "";
        telefone = "";
        email = "";
      }
   };

// [...]

Remembering that the field r1000.evtInfoContri.id has a specific assembly rule, which you can check on page 43 of Developer Guidance Manual EFD-Reinf v1.3.03:

inserir a descrição da imagem aqui

3: How to serializo the full event? since the full event is composed of several classes. I tried so and it only generates the first block.

I believe you can use this code even though you posted it in the question. The generated XML only had the first block because this is the only object present in the event structure, all other groups/objects are empty/null. Once everything is filled correctly, when serializing everything will appear in the generated XML.

Remembering that, usually the class XmlSerializer places the attributes xmlns:xsi and xmlns:xsd in the root element, and according to the documentation, there should only be the namespace of Reinf itself in the root element.

As the class XmlSerializer normally generates the XML:

<?xml version="1.0" encoding="utf-8"?>
<Reinf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       xmlns="http://www.reinf.esocial.gov.br/schemas/evtInfoContribuinte/v1_04_00">
   [...]
</Reinf>

As it should be:

<?xml version="1.0" encoding="utf-8"?>
<Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/evtInfoContribuinte/v1_04_00">
   [...]
</Reinf>

I use the following functions to serialize objects:

// Versão que serializa o objeto para o tipo XDocument.
public static XDocument SerializeToXDoc(object obj)
{
   // O elemento raiz não pode conter os atributos 'xmlns:xsi' e 'xmlns:xsd',
   // mas deve conter o atributo 'xmlns="http://www.reinf.esocial.gov.br/[...]'.
   var ns = GetSerializerNamespace(obj);

   var xDoc = new XDocument();
   using (XmlWriter writer = xDoc.CreateWriter())
   {
      var xs = new XmlSerializer(obj.GetType());
      xs.Serialize(writer, obj, ns);
   }
   return xDoc;
}

// Versão que serializa o objeto para o tipo XmlDocument.
public static XmlDocument SerializeToXmlDoc(object obj)
{
   // O elemento raiz não pode conter os atributos 'xmlns:xsi' e 'xmlns:xsd',
   // mas deve conter o atributo 'xmlns="http://www.reinf.esocial.gov.br/[...]'.
   var ns = GetSerializerNamespace(obj);
 
   var xmlDoc = new XmlDocument();
   var nav = xmlDoc.CreateNavigator();
   using (XmlWriter writer = nav.AppendChild())
   {
      var xs = new XmlSerializer(obj.GetType());
      xs.Serialize(writer, obj, ns);
   }
   return xmlDoc;
}

private static XmlSerializerNamespaces GetSerializerNamespace(object obj)
{
   // Pega o namespace definido para a classe que se deseja serializar, pelo atributo XML.
   // Exemplo: 'xmlns="http://www.reinf.esocial.gov.br/[...]'.
   var xmlAttrib = (XmlTypeAttribute) Attribute.GetCustomAttribute(obj.GetType(),
                                                                   typeof(XmlTypeAttribute));
   string nsClasse = xmlAttrib?.Namespace ?? "";
   // Informa que o elemento raiz do XML que será gerado não deve incluir os atributos
   // 'xmlns:xsi' e 'xmlns:xsd', mas deve incluir o namespace da classe que se deseja serializar.
   var ns = new XmlSerializerNamespaces();
   ns.Add("", nsClasse);
   return ns;
}
  • OK. Should I do the same procedure for Communication XSD(s) Package(s? mailLoteEvents-v1_04_00.xsd for example?

  • 1

    Must do It’s kind of a strong term, hehe... you can do it that way, although you can do it in other ways, too, but I find this one easier and more practical. I do so (by converting the communication scheme into objects as well). Then I sign the events and I will embed in the communication object (sending the lot), as in the answer I gave you (https://answall.com/a/277475/86952), and in the end I serializo the lot with these same functions, and there it is ready for sending!

  • Well, I believe it evolves, because in the return string already appears the word "SUCCESS"... Value: "xxxxxxxxxxxxxxSUCESSO1016286041ERRO1MS0030The structure of the XML file is in disagreement with the XSD schema. The 'URI' attribute is invalid - The value '' is invalid According to its datatype 'Anyuri'. I used the post: https://answall.com/questions/248928/reinf-assinatura-inv%C3%A1lida/ to get to this point. I would like to comment on this same post because I believe my problem would be a sequence of this...

  • 1

    @Vagnercosta, look at this answer here: EFD-Reinf: Invalid signature - Failed to verify XML document signature (using C#). In eSocial the attribute URI of the element Reference should be empty, but in EFD-Reinf it should contain the event ID (the same as the rule I commented on in the reply), in the form: "#Iddoevento".

  • worked out!! finally managed to transmit successfully! Thanks so much for the help!

  • 1

    Good Vagner! You’re welcome. Just yesterday I posted another question in which I modified a little this XML signature function, specifically for EFD-Reinf, maybe it will help you: EDF-Reinf: Signature Error - A Xmldocument Context is Required for Enveloped Transformations.

  • And just to remind you, now that you have more than 15 reputation points you can already vote in favour of an answer or question. See also: Why it is important to vote?. The votes in favor help me, of course ;-), but help the community in general as well. Try to create a habit of always voting on what you find useful. Just be careful not to give too many votes to the same person in one day: What are the limits to entering the voting fraud rule?.

  • Oh yes, and votes against also help the community. If you find a question or answer that is very bad, or incorrect, vote against. so signals to other people that that question or answer is not good.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.