Unfulfilled Nfe XML

Asked

Viewed 3,047 times

4

Well, I’m trying to do the reading for import of XMLs of the Electronic Tax Notes and I’m having a lot of difficulty in disemboweling the ICMS of the blessed.

No problems to reach the object ICMS:

object objeto = ListaItens[i].imposto.Items[0]

This returns an object of the type TNFeInfNFeDetImpostoICMS and here is the description of this class:

public partial class TNFeInfNFeDetImpostoICMS {

    private object itemField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ICMS00", typeof(TNFeInfNFeDetImpostoICMSICMS00))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS10", typeof(TNFeInfNFeDetImpostoICMSICMS10))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS20", typeof(TNFeInfNFeDetImpostoICMSICMS20))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS30", typeof(TNFeInfNFeDetImpostoICMSICMS30))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS40", typeof(TNFeInfNFeDetImpostoICMSICMS40))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS51", typeof(TNFeInfNFeDetImpostoICMSICMS51))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS60", typeof(TNFeInfNFeDetImpostoICMSICMS60))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS70", typeof(TNFeInfNFeDetImpostoICMSICMS70))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS90", typeof(TNFeInfNFeDetImpostoICMSICMS90))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSPart", typeof(TNFeInfNFeDetImpostoICMSICMSPart))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN101", typeof(TNFeInfNFeDetImpostoICMSICMSSN101))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN102", typeof(TNFeInfNFeDetImpostoICMSICMSSN102))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN201", typeof(TNFeInfNFeDetImpostoICMSICMSSN201))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN202", typeof(TNFeInfNFeDetImpostoICMSICMSSN202))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN500", typeof(TNFeInfNFeDetImpostoICMSICMSSN500))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN900", typeof(TNFeInfNFeDetImpostoICMSICMSSN900))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSST", typeof(TNFeInfNFeDetImpostoICMSICMSST))]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

What I would like to do is to sweep up all the "types" of ICMS to take their properties, but I couldn’t find any way to make a loop for disembobulating each element.

Can help?

EDIT:

One thing I realized in practice (I don’t have much tax knowledge) is that each item in the XML will present only one of these classes of ICMS encapsulated, so all you had to do was find a way to unbox of the object choosing at runtime the class contained. Is there any way to do this?

EDIT2:

I do the deserialization as follows:

I have a class Serializer:

public static class Serializer
    {
        public static T Deserialize<T>(this XElement xElement) 
        {
            using (var memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString())))
            {
                var xmlSerializer = new XmlSerializer(typeof(T));
                return (T)xmlSerializer.Deserialize(memoryStream);
            }
        }

        public static XElement Serialize<T>(this object o)
        {
            using (var memoryStream = new MemoryStream())
            {
                using (TextWriter streamWriter = new StreamWriter(memoryStream))
                {
                    var xmlSerializer = new XmlSerializer(typeof(T));
                    xmlSerializer.Serialize(streamWriter, o);
                    return XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));
                }
            }
        }
    }

And a class ProcNFe_v3_10 generated from the .xsd I picked up on the farm site (I will not post because it is too extensive).

So first I carry one XElement with my .xml:

XElement xElement = XElement.Load(ofdXml.FileName);

Being ofdXml one OpenFileDialog.

And later I call the method deserializer of my class passing TNfeProc as a type T (which is the corresponding type of my grade, contained within the class ProcNFe_v3_10) and the xElement loaded as attribute, as follows:

TNfeProc NFCarregada = Serializer.Deserialize<TNfeProc>(xElement);

And voilà, I have mine XML deserialized.

  • http://answall.com/questions/44130/leitura-xml-nfe?rq=1

  • Actually @Hstackoverflow, I’m already utilizing the deserialization of the XML from the original Nfe schema. My problem is getting to that specific information. The rest of the data I’ve been able to extract.

  • Are you doing deserialization? You can post the code?

  • Sorry for the delay. I edited the question adding the deserialization.

  • Can be with LINQ?

  • It will be a great time for me to learn how to work with LINQ. Send!

Show 1 more comment

3 answers

1


Here comes a solution:

static void Main(string[] args)
    {
        string fileName = "c:\\temp\\arquivo.xml";
        var nfe = XElement.Load(fileName);
        var nfeCarregada = Serializer.Deserialize<TNfeProc>(nfe);

        var imp = nfeCarregada.NFe.infNFe.det.Select(x => x.imposto);
        foreach (var imposto in imp)
        {
            if (imposto.PIS.Item.GetType().Name == "TNFeInfNFeDetImpostoPISPISNT")
            {
                var pisNT = (TNFeInfNFeDetImpostoPISPISNT)imposto.PIS.Item;
                Console.WriteLine(String.Format("PISNT: \nCST:{0}",  pisNT.CST));
            }
            else if (imposto.PIS.Item.GetType().Name == "TNFeInfNFeDetImpostoPISPISAliq")
            {
                var pisAliq = (TNFeInfNFeDetImpostoPISPISAliq)imposto.PIS.Item;
                Console.WriteLine(String.Format("PISAliq: CST:{0}\nvBC:{1}\nvPIS:{2}", pisAliq.CST, pisAliq.vBC, pisAliq.vPIS));
            }//CONTINUA

            if (imposto.COFINS.Item.GetType().Name == "TNFeInfNFeDetImpostoCOFINSCOFINSNT")
            {
                var cofins = (TNFeInfNFeDetImpostoCOFINSCOFINSNT)imposto.COFINS.Item;
                Console.WriteLine(String.Format("COFINS: \nCST:{0}", cofins.CST));
            }//CONTINUA

            foreach (var itemImposto in imposto.Items.Select(x => x.Serialize<TNFeInfNFeDetImpostoICMS>()))
            {
                var tipoICMS = itemImposto.Elements().ElementAtOrDefault(0).Name.LocalName;
                if (tipoICMS.ToString() == "ICMS60")
                {
                    var icms = (TNFeInfNFeDetImpostoICMSICMS60)Serializer.Deserialize<TNFeInfNFeDetImpostoICMS>(itemImposto).Item;
                    Console.WriteLine(string.Format("CST {0} ORIGEM {1}", icms.CST, icms.orig));
                }
                else if (tipoICMS.ToString() == "ICMS00")
                {
                    var icms = (TNFeInfNFeDetImpostoICMSICMS00)Serializer.Deserialize<TNFeInfNFeDetImpostoICMS>(itemImposto).Item;
                    Console.WriteLine(string.Format("ICMS00:\nCST {0} \norig {1} \nmodBC {2} \npICMS {3} \nvBC {4} \nvICMS {5}",
                        icms.CST, icms.orig, icms.modBC, icms.pICMS, icms.vBC, icms.vICMS));
                }//..continua
            }
        }
    }

Upshot: Resultado Deserialização NFe

Obs: I can’t unserialize guys "item" (see image CST field) if you can get the values of these fields please share this code :).

  • 1

    Man, congratulations and thanks for your solution. I added to my program and it worked great! I will implement and try to solve the case the type item. Just tell me, why did you compare just to ICMS00 and ICMS60?

  • See what below has //..continua as it was just a test I didn’t implement everything, the correct thing is to compare it with everyone. If you solve the problem of item` please put here in the comments. @Cassiomilanelo

  • 1

    I figured that’s right, I just found it curious to be the 00 and the 60, which are the most common in my case.

  • 1

    I found a flaw in the code: in the last foreach where there is the reading of the ICMS, is made the serialization of all the content of imposto.Items passing the class TNFeInfNFeDetImpostoICMS as type. The error happens when there are other types within the object, such as TIpi, for example.

  • Post the correction here that I add in the reply, in case I can not correct sends the XML pro link that generates this error.

0

I ended up using a for to scan the contents of Item and a Switch to select the correct class (which seemed to me a very bad service, by the way):

string porcICMS;
string porcIPI;
for (int j = 0; j < (ListaItens[i].imposto.Items.Length); j++)
{
    switch (ListaItens[i].imposto.Items[j].GetType().ToString())
    {
        case "TNFeInfNFeDetImpostoICMS": 
            object ICMS = (((TNFeInfNFeDetImpostoICMS)(ListaItens[i].imposto.Items[j])).Item);

            switch (ICMS.GetType().ToString())
            {
                case "TNFeInfNFeDetImpostoICMSICMS00": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS00)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS10": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS10)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS20": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS20)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS51": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS51)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS60": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS60)ICMS).vICMSSTRet;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS70": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS70)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS90": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS90)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMSPart": porcICMS = ((TNFeInfNFeDetImpostoICMSICMSPart)ICMS).pICMS;
                    break;
            }
            break;

        case "TIpi":
            object IPI = (((TIpi)(ListaItens[i].imposto.Items[j])).Item);
            porcIPI = ((TIpiIPITrib)IPI).Items[1];
            break;

        default:
            porcICMS = "0.0000";
            porcIPI = "0.0000";
            break;
    }
}

But it worked. In IPI there is yet another object Item that I used the Item[1], which corresponds to the percentage.

Again, it seems to me to be an amateur service what I did. If you have another solution, share it.

  • Post the XML pro link for me to test.

0

I was having the same problem to serialize the ICMS, then I dropped it that the knot .imposto.Items asks for a new object[] so I was able to solve here in my code the following way:

//Criar os novos objetos de impostos possíveis para o produto!
nfe.infNFe.det[index].imposto.Items = new object[4] { ICMS, II, TIpi, ISSQN };

//Desencapsulando!
nfe.infNFe.det[index].imposto.Items[0] = new TNFeInfNFeDetImpostoICMS()
{
   Item = new TNFeInfNFeDetImpostoICMSICMS00()
   {
     orig = Torig.Item0,
     CST = TNFeInfNFeDetImpostoICMSICMS00CST.Item00,
     modBC = TNFeInfNFeDetImpostoICMSICMS00ModBC.Item0,
     vBC = "0.00",
     pICMS = "0.00",
     pFCP = "0.00",
     vFCP = "0.00"
   }
}; 

I hope I’ve helped!

Browser other questions tagged

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