Ejemplo n.º 1
0
        private void btnTimbraCfdiEntidad_Click(object sender, EventArgs e)
        {
            //Este ejemplo está dirigido a aquellos integradores que aún no generan el xml (CFDI)

            //Inicializamos el conector el parámetro indica el ambiente en el que se utilizará
            //Fasle = Ambiente de pruebas
            //True = Ambiente de producción
            Conector conector = new Conector(false);

            //Establecemos las credenciales para el permiso de conexión
            //Ambiente de pruebas = mvpNUXmQfK8=
            //Ambiente de producción = Esta será asignado por el proveedor al salir a productivo
            conector.EstableceCredenciales("mvpNUXmQfK8=");

            //Creamos un comprobante por medio de la entidad Comprobante
            Comprobante comprobante = new Comprobante();

            //Llenamos datos del comprobante
            comprobante.serie        = "F";
            comprobante.folio        = "1";
            comprobante.fecha        = DateTime.Now;
            comprobante.formaDePago  = "Pago en una sola exhibición";
            comprobante.metodoDePago = "Transferencia bancaria";
            comprobante.subTotal     = 100;
            comprobante.total        = 116;
            //TIPO DE COMPROBANTE
            //Ingreso: Factura 1, Rec honorarios 4, rec de arrendamiento 5, Rec donativos 7, Nota de cargo 3
            //Egreso: Nota de credito 2
            //Traslado: Carta porte  6
            comprobante.tipoDeComprobante = ComprobanteTipoDeComprobante.ingreso;
            comprobante.LugarExpedicion   = "Mexico, Distrito Federal";

            //Llenamos datos del emisor
            comprobante.Emisor        = new ComprobanteEmisor();
            comprobante.Emisor.rfc    = "AAA010101AAA";
            comprobante.Emisor.nombre = "Empresa de pruebas S.A. de C.V.";

            //Llenamos domicilio fiscal del emisor
            comprobante.Emisor.DomicilioFiscal              = new t_UbicacionFiscal();
            comprobante.Emisor.DomicilioFiscal.calle        = "Calle pruebas";
            comprobante.Emisor.DomicilioFiscal.noExterior   = "1";
            comprobante.Emisor.DomicilioFiscal.noInterior   = "A";
            comprobante.Emisor.DomicilioFiscal.colonia      = "Colonia pruebas";
            comprobante.Emisor.DomicilioFiscal.municipio    = "Municipio pruebas";
            comprobante.Emisor.DomicilioFiscal.estado       = "Estado pruebas";
            comprobante.Emisor.DomicilioFiscal.pais         = "Mexico";
            comprobante.Emisor.DomicilioFiscal.codigoPostal = "53125";

            //Llenamos regimen fiscal del emisor
            comprobante.Emisor.RegimenFiscal            = new ComprobanteEmisorRegimenFiscal[1];
            comprobante.Emisor.RegimenFiscal[0]         = new ComprobanteEmisorRegimenFiscal();
            comprobante.Emisor.RegimenFiscal[0].Regimen = "Regimen general de ley personas morales";

            //Llena datos de expedido en (Solo en caso de que el comprobante haya sido expedido en una sucursal y no en la matriz
            comprobante.Emisor.ExpedidoEn              = new t_Ubicacion();
            comprobante.Emisor.ExpedidoEn.calle        = "Calle expedido en";
            comprobante.Emisor.ExpedidoEn.noExterior   = "2";
            comprobante.Emisor.ExpedidoEn.noInterior   = "B";
            comprobante.Emisor.ExpedidoEn.colonia      = "Colonia expedido en";
            comprobante.Emisor.ExpedidoEn.municipio    = "Municipio expedido en";
            comprobante.Emisor.ExpedidoEn.estado       = "Estado expedido en";
            comprobante.Emisor.ExpedidoEn.pais         = "Mexico";
            comprobante.Emisor.ExpedidoEn.codigoPostal = "53120";

            //Llena datos del receptor
            comprobante.Receptor        = new ComprobanteReceptor();
            comprobante.Receptor.rfc    = "BBB010101BBB";
            comprobante.Receptor.nombre = "Cliente de prueba S.A. de C.V.";

            //Llena domicilio del receptor
            comprobante.Receptor.Domicilio              = new t_Ubicacion();
            comprobante.Receptor.Domicilio.calle        = "Calle cliente";
            comprobante.Receptor.Domicilio.noExterior   = "3";
            comprobante.Receptor.Domicilio.noInterior   = "C";
            comprobante.Receptor.Domicilio.colonia      = "Colonia cliente";
            comprobante.Receptor.Domicilio.municipio    = "Municipio cliente";
            comprobante.Receptor.Domicilio.estado       = "Estado cliente";
            comprobante.Receptor.Domicilio.pais         = "México";
            comprobante.Receptor.Domicilio.codigoPostal = "5";

            //Llenamos los conceptos
            comprobante.Conceptos = new ComprobanteConcepto[2];

            //Concepto 1
            comprobante.Conceptos[0]                  = new ComprobanteConcepto();
            comprobante.Conceptos[0].cantidad         = 1;
            comprobante.Conceptos[0].unidad           = "PZA";
            comprobante.Conceptos[0].noIdentificacion = "1";
            comprobante.Conceptos[0].descripcion      = "Prueba concepto 1";
            comprobante.Conceptos[0].valorUnitario    = 50;
            comprobante.Conceptos[0].importe          = 50;

            //Concepto 2
            comprobante.Conceptos[1]                  = new ComprobanteConcepto();
            comprobante.Conceptos[1].cantidad         = 1;
            comprobante.Conceptos[1].unidad           = "PZA";
            comprobante.Conceptos[1].noIdentificacion = "1";
            comprobante.Conceptos[1].descripcion      = "Prueba concepto 2";
            comprobante.Conceptos[1].valorUnitario    = 50;
            comprobante.Conceptos[1].importe          = 50;

            //Llenamos impuestos
            comprobante.Impuestos                       = new ComprobanteImpuestos();
            comprobante.Impuestos.Traslados             = new ComprobanteImpuestosTraslado[1];
            comprobante.Impuestos.Traslados[0]          = new ComprobanteImpuestosTraslado();
            comprobante.Impuestos.Traslados[0].importe  = 16;
            comprobante.Impuestos.Traslados[0].impuesto = ComprobanteImpuestosTrasladoImpuesto.IVA;
            comprobante.Impuestos.Traslados[0].tasa     = 16;

            List <XmlElement> LXmlComplementos = new List <XmlElement>();

            ImpuestosLocales impLocales = new ImpuestosLocales();
            List <ImpuestosLocalesTrasladosLocales> traslados = new List <ImpuestosLocalesTrasladosLocales>();

            //Agregamos una retención local
            ImpuestosLocalesTrasladosLocales traslado = new ImpuestosLocalesTrasladosLocales();

            traslado.Importe          = 12;
            traslado.ImpLocTrasladado = "Impuesto sobre hospedaje";
            traslado.TasadeTraslado   = 2;

            traslados.Add(traslado);

            impLocales.TrasladosLocales = traslados.ToArray <ImpuestosLocalesTrasladosLocales>();
            impLocales.version          = "1.0";

            //Totales
            impLocales.TotaldeRetenciones = 0;
            impLocales.TotaldeTraslados   = 20;

            XmlSerializerNamespaces nsImpLocales = new XmlSerializerNamespaces();

            nsImpLocales.Add("implocal", "http://www.sat.gob.mx/implocal");
            string xmlImpLocales = XMLUtilerias.SerializaObjeto(impLocales, typeof(ImpuestosLocales), nsImpLocales);

            XmlDocument docImpuestosLocales = new XmlDocument();

            docImpuestosLocales.LoadXml(xmlImpLocales);
            comprobante.ImpLocalSpecified = true;
            LXmlComplementos.Add(docImpuestosLocales.DocumentElement);

            comprobante.Complemento     = new ComprobanteComplemento();
            comprobante.Complemento.Any = LXmlComplementos.ToArray <XmlElement>();



            ////INICIA EJEMPLO PARA COMPLEMENTO NÓMINA
            ////Descomentar esta sección para utilizar el complemento nómina

            ////Declaramos arreglo de complementos
            //List<XmlElement> LXmlComplementos = new List<XmlElement>();

            ////Lenamos clase Nomina con datos
            //Nomina nomina = new Nomina();
            //nomina.RegistroPatronal = "1234567890";
            //nomina.NumEmpleado = "1";
            //nomina.CURP = "AAAA800101HDFTRN04";
            //nomina.TipoRegimen = 1;
            //nomina.NumSeguridadSocial = "1234567890";
            //nomina.FechaPago = DateTime.Now;
            //nomina.FechaInicialPago = DateTime.Now;
            //nomina.FechaFinalPago = DateTime.Now;
            //nomina.NumDiasPagados = 15;
            //nomina.Departamento = "DESARROLLO";
            //nomina.CLABE = "123456789012345678";
            //nomina.Banco = "001";
            //if (nomina.Banco != null)
            //    nomina.BancoSpecified = true;
            //else
            //    nomina.BancoSpecified = false;
            //nomina.FechaInicioRelLaboral = DateTime.Now;
            //if (nomina.FechaInicioRelLaboral != null)
            //    nomina.FechaInicioRelLaboralSpecified = true;
            //else
            //    nomina.FechaInicioRelLaboralSpecified = false;
            //nomina.Antiguedad = 45;
            //if (nomina.Antiguedad != 0)
            //    nomina.AntiguedadSpecified = true;
            //else
            //    nomina.AntiguedadSpecified = false;
            //nomina.Puesto = "PROGRAMADOR";
            //nomina.TipoContrato = "BASE";
            //nomina.TipoJornada = "DIURNA";
            //nomina.PeriodicidadPago = "QUINCENAL";
            //nomina.SalarioBaseCotApor = 1000;
            //if (nomina.SalarioBaseCotApor != 0)
            //    nomina.SalarioBaseCotAporSpecified = true;
            //else
            //    nomina.SalarioBaseCotAporSpecified = false;
            //nomina.RiesgoPuesto = 1;
            //if (nomina.RiesgoPuesto != 0)
            //    nomina.RiesgoPuestoSpecified = true;
            //else
            //    nomina.RiesgoPuestoSpecified = false;
            //nomina.SalarioDiarioIntegrado = 150;
            //if (nomina.SalarioDiarioIntegrado != 0)
            //    nomina.SalarioDiarioIntegradoSpecified = true;
            //else
            //    nomina.SalarioDiarioIntegradoSpecified = false;

            //nomina.Percepciones = new NominaPercepciones();
            //nomina.Percepciones.Percepcion = new NominaPercepcionesPercepcion[1];
            //nomina.Percepciones.TotalExento = 100;
            //nomina.Percepciones.TotalGravado = 200;

            //nomina.Percepciones.Percepcion[0] = new NominaPercepcionesPercepcion();
            //nomina.Percepciones.Percepcion[0].TipoPercepcion = "001";
            //nomina.Percepciones.Percepcion[0].Clave = "1";
            //nomina.Percepciones.Percepcion[0].Concepto = "SALARIO";
            //nomina.Percepciones.Percepcion[0].ImporteGravado = 1000;
            //nomina.Percepciones.Percepcion[0].ImporteExento = 500;

            //System.Xml.Serialization.XmlSerializerNamespaces nsNominas = new System.Xml.Serialization.XmlSerializerNamespaces();
            //nsNominas.Add("nomina", "http://www.sat.gob.mx/nomina");
            //string xmlNomina = XMLUtilerias.SerializaObjeto(nomina, typeof(Nomina), nsNominas);
            //XmlDocument docNominas = new XmlDocument();
            //docNominas.LoadXml(xmlNomina);
            //comprobante.NominasSpecified = true;
            //LXmlComplementos.Add(docNominas.DocumentElement);
            ////FIN EJEMPLO PARA COMPLEMENTO NÓMINA



            ////INICIA EJEMPLO PARA COMPLEMENTO IMPUESTOS LOCALES
            ////Descomentar esta sección para utilizar el complemento impuestos locales

            ////Declaramos arreglo de complementos
            //List<XmlElement> LXmlComplementos = new List<XmlElement>();

            //ImpuestosLocales impLocales = new ImpuestosLocales();
            //List<ImpuestosLocalesTrasladosLocales> traslado = new List<ImpuestosLocalesTrasladosLocales>();

            //ImpuestosLocalesTrasladosLocales tras = new ImpuestosLocalesTrasladosLocales();
            //tras.Importe = 13;
            //tras.ImpLocTrasladado = "Traslado local ejemplo";
            //tras.TasadeTraslado = 13;

            //traslado.Add(tras);

            //impLocales.TrasladosLocales = traslado.ToArray<ImpuestosLocalesTrasladosLocales>();
            //impLocales.version = "1.0";

            ////Totales
            //impLocales.TotaldeTraslados = 13;
            //impLocales.TotaldeRetenciones = 0;

            //XmlSerializerNamespaces nsImpLocales = new XmlSerializerNamespaces();
            //nsImpLocales.Add("implocal", "http://www.sat.gob.mx/implocal");
            //string xmlImpLocales = XMLUtilerias.SerializaObjeto(impLocales, typeof(ImpuestosLocales), nsImpLocales);

            //XmlDocument docImpuestosLocales = new XmlDocument();
            //docImpuestosLocales.LoadXml(xmlImpLocales);
            //comprobante.ImpLocalSpecified = true;
            //LXmlComplementos.Add(docImpuestosLocales.DocumentElement);
            ////FIN EJEMPLO PARA COMPLEMENTO IMPUESTOS LOCALES



            ////COMPLEMENTOS UTILIZADOS?
            ////Descomentar esta sección si utilizaste algún complemento como nóminas, impuestos locales, donativos, estados de cuenta etc..
            //comprobante.Complemento = new ComprobanteComplemento();
            //comprobante.Complemento.Any = LXmlComplementos.ToArray<XmlElement>();



            ////INICIA EJEMPLO PARA ADDENDAS
            ////Descomentar esta sección para agregar una addenda al comprobante

            ////Creamos nuestra addenda
            //string miAddendaEjemplo = "<Documento><Cabezero dato=\"valor\" dato2=\"valor2\"><Cuerpo datoCuerpo=\"valorCuerpo\" datoCuerpo2=\"valorCuerpo2\"/></Cabezero></Documento>";

            ////Transformamos a XmlElement
            //System.Xml.XmlDocument docAddenda = new System.Xml.XmlDocument();
            //docAddenda.LoadXml(miAddendaEjemplo);
            //XmlElement xmlAdenda = docAddenda.DocumentElement;

            ////Agregamos addenda
            //comprobante.Addenda = new ComprobanteAddenda();
            //comprobante.Addenda.Any = new XmlElement[1];
            //comprobante.Addenda.Any[0] = xmlAdenda;



            //Timbramos el CFDI por medio del conector y guardamos resultado
            ResultadoTimbre resultadoTimbre;

            resultadoTimbre = conector.TimbraCFDI(comprobante);

            //Verificamos el resultado
            if (resultadoTimbre.Exitoso)
            {
                //El comprobante fue timbrado exitosamente

                //Guardamos xml cfdi
                if (resultadoTimbre.GuardaXml("C:\\", "timbrado"))
                {
                    MessageBox.Show("El xml fue guardado correctamente");
                }
                else
                {
                    MessageBox.Show("Ocurrió un error al guardar el comprobante");
                }

                //Los siguientes datos deberán ir en la respresentación impresa ó PDF

                //1.- Código bidimensional
                if (resultadoTimbre.GuardaCodigoBidimensional("C:\\", "codigo"))
                {
                    MessageBox.Show("El código bidimensional fue guardado correctamente");
                }
                else
                {
                    MessageBox.Show("Ocurrió un error al guardar el código bidimensional");
                }

                //2.- Folio fiscal
                string folioFiscal = resultadoTimbre.FolioUUID;

                //3.- No. Certificado del Emisor
                string noCertificado = resultadoTimbre.No_Certificado;

                //4.- No. Certificado del SAT
                string noCertificadoSAT = resultadoTimbre.No_Certificado_SAT;

                //5.- Fecha y Hora de certificación
                string fechaCert = resultadoTimbre.FechaCertificacion;

                //6.- Sello del cfdi
                string selloCFDI = resultadoTimbre.SelloCFDI;

                //7.- Sello del SAT
                string selloSAT = resultadoTimbre.SelloSAT;

                //8.- Cadena original de complemento de certificación
                string cadena = resultadoTimbre.CadenaTimbre;

                MessageBox.Show("Timbrado Exitoso");
            }
            else
            {
                //No se pudo timbrar, mostramos respuesta
                MessageBox.Show(resultadoTimbre.Descripcion);
            }
        }
Ejemplo n.º 2
0
        public EntResultadoTimbrado EmitirComprobante(EntComprobante comprobante, bool emitidoEnMatriz)
        {
            try
            {
                // Se valida que el componente no sea null
                if (comprobante == null)
                {
                    throw new ArgumentNullException(nameof(comprobante));
                }

                // El comprobante debe tener al menos un concepto
                var totalProductos = comprobante.ComprobanteDetalle.Count;
                if (totalProductos == 0)
                {
                    throw new Exception("El comprobante no tiene conceptos definidos, agregue un por lo menos un concepto para emitir el comprobante");
                }

                // Inicializamos el conector y establecemos las credenciales para el permiso de conexión
                var conector = new Conector(_ambienteProductivo);

                conector.EstableceCredenciales(_usuarioIntegrador);

                //Creamos un comprobante por medio de la entidad Comprobante
                var CFDi = new Comprobante();

                // Llenamos datos del comprobante
                switch (comprobante.TipoComprobante.ToLower())
                {
                case "ingreso":
                    CFDi.TipoDeComprobante = "I";
                    break;

                case "egreso":
                    CFDi.TipoDeComprobante = "E";
                    break;

                case "traslado:":
                    CFDi.TipoDeComprobante = "T";
                    break;

                case "nomina":
                    CFDi.TipoDeComprobante = "N";
                    break;

                case "pago":
                    CFDi.TipoDeComprobante = "P";
                    break;
                }
                CFDi.Serie               = string.IsNullOrEmpty(comprobante.Serie.Trim()) ? null : comprobante.Serie.Trim();
                CFDi.Folio               = comprobante.Folio.ToString();
                CFDi.Version             = "3.3";
                CFDi.Fecha               = comprobante.FechaEmision;
                CFDi.FormaPago           = comprobante.FormaPago;
                CFDi.FormaPagoSpecified  = true;
                CFDi.MetodoPago          = comprobante.MetodoPago;
                CFDi.MetodoPagoSpecified = true;
                CFDi.Total               = comprobante.Total.ToDecimal();
                CFDi.SubTotal            = comprobante.Subtotal.ToDecimal();
                CFDi.LugarExpedicion     = comprobante.LugarExpedicion;
                CFDi.CondicionesDePago   = string.IsNullOrEmpty(comprobante.CondicionesPago.Trim()) ? null : comprobante.CondicionesPago.Trim();
                if (comprobante.Descuento != null && comprobante.Descuento.Value > 0)
                {
                    CFDi.Descuento          = comprobante.Descuento.Value.ToDecimal();
                    CFDi.DescuentoSpecified = true;
                }
                CFDi.Moneda              = comprobante.Moneda;
                CFDi.TipoCambio          = comprobante.TipoCambio.Value;
                CFDi.TipoCambioSpecified = true;

                // Folio del comprobante original (para parcialidades)
                // Serie del comprobante original (para parcialidades)
                // Fecha del comprobante original (para parcialidades)
                // Monto del comprobante original (para parcialidades)

                //Llenamos datos del emisor
                CFDi.Emisor = new ComprobanteEmisor
                {
                    Rfc           = comprobante.EmisorRfc,
                    Nombre        = comprobante.EmisorNombre,
                    RegimenFiscal = comprobante.RegimenFiscal
                };

                //Llena datos del receptor
                CFDi.Receptor = new ComprobanteReceptor
                {
                    Rfc     = comprobante.ReceptorRfc,
                    Nombre  = comprobante.ReceptorNombre,
                    UsoCFDI = comprobante.UsoCFDi
                };

                //Llenamos los conceptos
                CFDi.Conceptos = new ComprobanteConcepto[totalProductos];
                var indx = 0;
                foreach (var detalle in comprobante.ComprobanteDetalle.ToList())
                {
                    CFDi.Conceptos[indx] = new ComprobanteConcepto();
                    CFDi.Conceptos[indx].ClaveProdServ    = detalle.ClaveProdServ;
                    CFDi.Conceptos[indx].ClaveUnidad      = detalle.ClaveUnidad;
                    CFDi.Conceptos[indx].Cantidad         = detalle.Cantidad;
                    CFDi.Conceptos[indx].Unidad           = detalle.Unidad;
                    CFDi.Conceptos[indx].NoIdentificacion = !string.IsNullOrEmpty(detalle.NoIdentificacion) ? detalle.NoIdentificacion : null;
                    CFDi.Conceptos[indx].Descripcion      = detalle.Descripcion;
                    CFDi.Conceptos[indx].ValorUnitario    = Math.Round(detalle.ValorUnitario, 2);
                    CFDi.Conceptos[indx].Importe          = Math.Round(detalle.Importe, 2);

                    if (detalle.TieneInformacionAduanera)
                    {
                        var informacionAduanera = new ComprobanteConceptoInformacionAduanera();
                        informacionAduanera.NumeroPedimento         = detalle.ComplementoAduana.NumeroPedimento;
                        CFDi.Conceptos[indx].InformacionAduanera    = new ComprobanteConceptoInformacionAduanera[1];
                        CFDi.Conceptos[indx].InformacionAduanera[0] = informacionAduanera;
                    }

                    if (detalle.Descuento != 0)
                    {
                        CFDi.Conceptos[indx].Descuento          = detalle.Descuento;
                        CFDi.Conceptos[indx].DescuentoSpecified = true;
                    }

                    if (detalle.TasaTraIva.HasValue)
                    {
                        CFDi.Conceptos[indx].Impuestos                                  = new ComprobanteConceptoImpuestos();
                        CFDi.Conceptos[indx].Impuestos.Traslados                        = new ComprobanteConceptoImpuestosTraslado[1];
                        CFDi.Conceptos[indx].Impuestos.Traslados[0]                     = new ComprobanteConceptoImpuestosTraslado();
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].Base                = detalle.Importe - detalle.Descuento;
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].Impuesto            = "002";
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].TipoFactor          = "Tasa";
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].Importe             = detalle.ImporteTraIva.Value;
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].ImporteSpecified    = true;
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].TasaOCuota          = detalle.TasaTraIva.Value.ToString();
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].TasaOCuotaSpecified = true;
                    }
                    if (detalle.TasaTraIeps.HasValue)
                    {
                        CFDi.Conceptos[indx].Impuestos                                  = new ComprobanteConceptoImpuestos();
                        CFDi.Conceptos[indx].Impuestos.Traslados                        = new ComprobanteConceptoImpuestosTraslado[1];
                        CFDi.Conceptos[indx].Impuestos.Traslados[0]                     = new ComprobanteConceptoImpuestosTraslado();
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].Base                = detalle.Importe - detalle.Descuento;
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].Impuesto            = "003";
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].TipoFactor          = "Tasa";
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].Importe             = detalle.ImporteTraIeps.Value;
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].ImporteSpecified    = true;
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].TasaOCuota          = detalle.TasaTraIeps.Value.ToString();
                        CFDi.Conceptos[indx].Impuestos.Traslados[0].TasaOCuotaSpecified = true;
                    }
                    if (detalle.TasaRetIva.HasValue)
                    {
                        CFDi.Conceptos[indx].Impuestos                           = new ComprobanteConceptoImpuestos();
                        CFDi.Conceptos[indx].Impuestos.Retenciones               = new ComprobanteConceptoImpuestosRetencion[1];
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0]            = new ComprobanteConceptoImpuestosRetencion();
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].Base       = detalle.Importe - detalle.Descuento;
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].Impuesto   = "002";
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].TipoFactor = "Tasa";
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].Importe    = detalle.ImporteRetIva.Value;
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].TasaOCuota = detalle.TasaRetIva.Value;
                    }
                    if (detalle.TasaRetIsr.HasValue)
                    {
                        CFDi.Conceptos[indx].Impuestos                           = new ComprobanteConceptoImpuestos();
                        CFDi.Conceptos[indx].Impuestos.Retenciones               = new ComprobanteConceptoImpuestosRetencion[1];
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0]            = new ComprobanteConceptoImpuestosRetencion();
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].Base       = detalle.Importe - detalle.Descuento;
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].Impuesto   = "001";
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].TipoFactor = "Tasa";
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].Importe    = detalle.ImporteRetIsr.Value;
                        CFDi.Conceptos[indx].Impuestos.Retenciones[0].TasaOCuota = detalle.TasaRetIsr.Value;
                    }

                    //Llenamos los complementos si existiera alguno
                    //if (detalle.Complementos.Count() > 0)
                    //{
                    //    CFDi.Conceptos[indx].Items = new Object[detalle.Complementos.Count()];
                    //    int compIndx = 0;
                    //    foreach (IComplementoConcepto complemento in detalle.Complementos)
                    //    {
                    //        var type = complemento.GetType();
                    //        switch (type.Name)
                    //        {
                    //            case "EntComplementoAduana":
                    //                var complementoAduana = complemento as EntComplementoAduana;

                    //                CFDi.Conceptos[indx].Items[compIndx] = new t_InformacionAduanera()
                    //                {
                    //                    aduana = complementoAduana.Nombre,
                    //                    numero = complementoAduana.Numero,
                    //                    fecha = complementoAduana.Fecha
                    //                };
                    //                break;
                    //            case "EntComplementoPredial":
                    //                var complementoPredial = complemento as EntComplementoPredial;

                    //                CFDi.Conceptos[indx].Items[compIndx] = new ComprobanteConceptoCuentaPredial()
                    //                {
                    //                    numero = complementoPredial.Numero
                    //                };
                    //                break;
                    //            case "EntComplementoParte":
                    //                var complementoParte = complemento as EntComplementoParte;

                    //                CFDi.Conceptos[indx].Items[compIndx] = new ComprobanteConceptoParte()
                    //                {
                    //                    cantidad = complementoParte.Cantidad,
                    //                    unidad = complementoParte.Unidad,
                    //                    noIdentificacion = complementoParte.NoIdentificacion,
                    //                    descripcion = complementoParte.Descripcion,
                    //                    valorUnitario = complementoParte.ValorUnitario,
                    //                    importe = complementoParte.Importe
                    //                };
                    //                break;
                    //        }
                    //        compIndx++;
                    //    }
                    //}

                    indx++;
                }

                //Se integran los impuestos
                var detalles           = comprobante.ComprobanteDetalle.ToList() as List <EntComprobanteDetalle>;
                var impuestosTraslado  = new List <EntImpuestoTraslado>();
                var impuestosRetencion = new List <EntImpuestoRetencion>();

                if (comprobante.ConceptosIncluyenImpuestos)
                {
                    foreach (EntComprobanteDetalle detalle in detalles)
                    {
                        if (detalle.TasaTraIva.HasValue)
                        {
                            impuestosTraslado.Add(new EntImpuestoTraslado()
                            {
                                Tipo = "IVA", TasaOCuota = detalle.TasaTraIva.Value, Importe = detalle.ImporteTraIva.Value
                            });
                        }
                        if (detalle.TasaTraIeps.HasValue)
                        {
                            impuestosTraslado.Add(new EntImpuestoTraslado()
                            {
                                Tipo = "IEPS", TasaOCuota = detalle.TasaTraIeps.Value, Importe = detalle.ImporteTraIeps.Value
                            });
                        }
                        if (detalle.TasaRetIva.HasValue)
                        {
                            impuestosRetencion.Add(new EntImpuestoRetencion()
                            {
                                Tipo = "IVA", TasaOCuota = detalle.TasaRetIva.Value, Importe = detalle.ImporteRetIva.Value
                            });
                        }
                        if (detalle.TasaRetIsr.HasValue)
                        {
                            impuestosRetencion.Add(new EntImpuestoRetencion()
                            {
                                Tipo = "ISR", TasaOCuota = detalle.TasaRetIsr.Value, Importe = detalle.ImporteRetIsr.Value
                            });
                        }
                    }
                }

                var impuestosTrasladoGroup = (from p in impuestosTraslado
                                              group p by new { p.Tipo, p.TasaOCuota }
                                              into grupo
                                              select new
                {
                    Tipo = grupo.Key.Tipo,
                    Tasa = grupo.Key.TasaOCuota,
                    Importe = grupo.Sum(x => x.Importe)
                }).ToList();

                var impuestosRetencionGroup = (from p in impuestosRetencion
                                               group p by new { p.Tipo, p.TasaOCuota }
                                               into grupo
                                               select new
                {
                    Tipo = grupo.Key.Tipo,
                    Tasa = grupo.Key.TasaOCuota,
                    Importe = grupo.Sum(x => x.Importe)
                }).ToList();

                if (!comprobante.EsPago)
                {
                    //Se registran los impuestos federales
                    CFDi.Impuestos = new ComprobanteImpuestos();

                    if (impuestosTrasladoGroup.Count > 0)
                    {
                        decimal totalImpuestosTrasladados = 0;
                        CFDi.Impuestos.Traslados = new ComprobanteImpuestosTraslado[impuestosTrasladoGroup.Count];

                        var i = 0;
                        foreach (var impuesto in impuestosTrasladoGroup)
                        {
                            CFDi.Impuestos.Traslados[i] = new ComprobanteImpuestosTraslado();
                            if (impuesto.Tipo == "IVA")
                            {
                                CFDi.Impuestos.Traslados[i].Impuesto   = "002";
                                CFDi.Impuestos.Traslados[i].TipoFactor = "Tasa";
                                CFDi.Impuestos.Traslados[i].TasaOCuota = impuesto.Tasa.ToString();
                                CFDi.Impuestos.Traslados[i].Importe    = impuesto.Importe.ToString("##0.00").ToDecimal();
                            }
                            if (impuesto.Tipo == "IEPS")
                            {
                                CFDi.Impuestos.Traslados[i].Impuesto   = "003";
                                CFDi.Impuestos.Traslados[i].TipoFactor = "Tasa";
                                CFDi.Impuestos.Traslados[i].TasaOCuota = impuesto.Tasa.ToString();
                                CFDi.Impuestos.Traslados[i].Importe    = impuesto.Importe.ToString("##0.00").ToDecimal();
                            }

                            totalImpuestosTrasladados += impuesto.Importe;
                            i++;
                        }

                        CFDi.Impuestos.TotalImpuestosTrasladados          = totalImpuestosTrasladados;
                        CFDi.Impuestos.TotalImpuestosTrasladadosSpecified = true;
                    }

                    if (impuestosRetencionGroup.Count > 0)
                    {
                        decimal totalImpuestosRetenidos = 0;
                        CFDi.Impuestos.Retenciones = new ComprobanteImpuestosRetencion[impuestosRetencionGroup.Count];

                        var i = 0;
                        foreach (var impuesto in impuestosRetencionGroup)
                        {
                            CFDi.Impuestos.Retenciones[i] = new ComprobanteImpuestosRetencion();
                            if (impuesto.Tipo == "IVA")
                            {
                                CFDi.Impuestos.Retenciones[i].Impuesto = "002";
                                CFDi.Impuestos.Retenciones[i].Importe  = impuesto.Importe.ToString("##0.00").ToDecimal();
                            }
                            if (impuesto.Tipo == "ISR")
                            {
                                CFDi.Impuestos.Retenciones[i].Impuesto = "001";
                                CFDi.Impuestos.Retenciones[i].Importe  = impuesto.Importe.ToString("##0.00").ToDecimal();
                            }

                            totalImpuestosRetenidos += impuesto.Importe;
                            i++;
                        }

                        CFDi.Impuestos.TotalImpuestosRetenidos          = totalImpuestosRetenidos;
                        CFDi.Impuestos.TotalImpuestosRetenidosSpecified = true;
                    }
                }

                // Se registran los complementos de la factura
                var xmlComplementos = new List <XmlElement>();

                // Complemento para pago
                if (comprobante.EsPago)
                {
                    var detallePago = new Profact.TimbraCFDI33.Complementos.Pagos10.PagosPago()
                    {
                        FechaPago            = comprobante.ComprobantesPagos.Fecha,
                        FormaDePagoP         = comprobante.ComprobantesPagos.FormaPago,
                        MonedaP              = comprobante.ComprobantesPagos.Moneda,
                        TipoCambioP          = comprobante.ComprobantesPagos.TipoCambio ?? comprobante.ComprobantesPagos.TipoCambio.ToDecimal(),
                        TipoCambioPSpecified = comprobante.ComprobantesPagos.TipoCambio != null,
                        Monto                = comprobante.ComprobantesPagos.Monto,
                        RfcEmisorCtaBen      = string.IsNullOrEmpty(comprobante.ComprobantesPagos.EmisorCuentaBenef) ? null : comprobante.ComprobantesPagos.EmisorCuentaBenef,
                        RfcEmisorCtaOrd      = string.IsNullOrEmpty(comprobante.ComprobantesPagos.EmisorCuentaOrigen) ? null : comprobante.ComprobantesPagos.EmisorCuentaOrigen,
                        CtaBeneficiario      = string.IsNullOrEmpty(comprobante.ComprobantesPagos.CuentaBeneficiaria) ? null : comprobante.ComprobantesPagos.CuentaBeneficiaria,
                        CtaOrdenante         = string.IsNullOrEmpty(comprobante.ComprobantesPagos.CuentaOrdenante) ? null : comprobante.ComprobantesPagos.CuentaOrdenante,
                        NomBancoOrdExt       = string.IsNullOrEmpty(comprobante.ComprobantesPagos.Banco) ? null : comprobante.ComprobantesPagos.Banco,
                        NumOperacion         = string.IsNullOrEmpty(comprobante.ComprobantesPagos.NumeroOperacion) ? null : comprobante.ComprobantesPagos.NumeroOperacion,
                        TipoCadPago          = string.IsNullOrEmpty(comprobante.ComprobantesPagos.TipoCadenaPago) ? null : comprobante.ComprobantesPagos.TipoCadenaPago,
                        TipoCadPagoSpecified = !string.IsNullOrEmpty(comprobante.ComprobantesPagos.TipoCadenaPago),
                        CadPago              = string.IsNullOrEmpty(comprobante.ComprobantesPagos.CadenaPago) ? null : comprobante.ComprobantesPagos.CadenaPago,
                        //CertPago
                        //SelloPago
                    };

                    var tieneComprobantesRelacionados = true;
                    if (tieneComprobantesRelacionados)
                    {
                        detallePago.DoctoRelacionado = new PagosPagoDoctoRelacionado[comprobante.ComprobantesPagos.DocumentosRelacionados.Count];
                        var i = 0;
                        foreach (var doc in comprobante.ComprobantesPagos.DocumentosRelacionados.ToList())
                        {
                            var doctoRelacionado = new Profact.TimbraCFDI33.Complementos.Pagos10.PagosPagoDoctoRelacionado()
                            {
                                IdDocumento               = doc.IdDocumento,
                                MonedaDR                  = doc.Moneda,
                                MetodoDePagoDR            = doc.MetodoPago,
                                NumParcialidad            = string.IsNullOrEmpty(doc.NumParcialidad.ToString()) ? null : doc.NumParcialidad.ToString(),
                                ImpSaldoAnt               = doc.ImpSaldoAnt ?? doc.ImpSaldoAnt.ToDecimal(),
                                ImpSaldoAntSpecified      = doc.ImpSaldoAnt != null,
                                ImpSaldoInsoluto          = doc.ImpSaldoInsoluto ?? doc.ImpSaldoInsoluto.ToDecimal(),
                                ImpSaldoInsolutoSpecified = doc.ImpSaldoInsoluto != null,
                                ImpPagado                 = doc.ImpPagado ?? doc.ImpPagado.ToDecimal(),
                                ImpPagadoSpecified        = doc.ImpPagado != null,
                                Folio                 = string.IsNullOrEmpty(doc.Folio) ? null : doc.Folio,
                                Serie                 = string.IsNullOrEmpty(doc.Serie) ? null : doc.Serie,
                                TipoCambioDR          = doc.TipoCambio ?? doc.TipoCambio.ToDecimal(),
                                TipoCambioDRSpecified = doc.TipoCambio != null
                            };

                            detallePago.DoctoRelacionado[i] = new PagosPagoDoctoRelacionado();
                            detallePago.DoctoRelacionado[i] = doctoRelacionado;
                            i++;
                        }
                    }

                    var pago = new Profact.TimbraCFDI33.Complementos.Pagos10.Pagos();
                    pago.Version = "1.0";
                    pago.Pago    = new PagosPago[1];
                    pago.Pago[0] = new PagosPago();
                    pago.Pago[0] = detallePago;

                    XmlSerializerNamespaces nsPagos = new XmlSerializerNamespaces();
                    nsPagos.Add("pago10", "http://www.sat.gob.mx/Pagos");
                    string xmlPagos = XMLUtilerias.SerializaObjeto(pago, typeof(Pagos), nsPagos);

                    XmlDocument docPago = new XmlDocument();
                    docPago.LoadXml(xmlPagos);

                    xmlComplementos.Add(docPago.DocumentElement);
                    CFDi.PagosSpecified = true;
                }

                // Impuestos locales
                //if (comprobante.ImpuestosLocales != null)
                //{
                //  if (comprobante.ImpuestosLocales.Count > 0)
                //  {
                //      XmlDocument impLocal = RegistrarImpuestosLocales(comprobante.ImpuestosLocales);
                //      xmlComplementos.Add(impLocal.DocumentElement);
                //      CFDi.ImpLocalSpecified = true;
                //  }
                //}

                // Se agregan los complementos
                if (xmlComplementos.Count > 0)
                {
                    CFDi.Complemento     = new Profact.TimbraCFDI33.ComprobanteComplemento();
                    CFDi.Complemento.Any = xmlComplementos.ToArray <XmlElement>();
                }

                //Timbramos el comprobante a traves de una petición al PAC
                var resultadoTimbre = conector.TimbraCFDI(CFDi);

                //Se mapean los resultados para ser devueltos por el servicio
                var resultado = new EntResultadoTimbrado
                {
                    Exitoso = resultadoTimbre.Exitoso,
                    Mensaje = resultadoTimbre.Descripcion
                };

                if (resultadoTimbre.Exitoso)
                {
                    resultado.FolioUuid          = resultadoTimbre.FolioUUID;           //2.- Folio fiscal
                    resultado.NoCertificado      = resultadoTimbre.No_Certificado;      //3.- No. Certificado del Emisor
                    resultado.NoCertificadoSat   = resultadoTimbre.No_Certificado_SAT;  //4.- No. Certificado del SAT
                    resultado.FechaCertificacion = resultadoTimbre.FechaCertificacion;  //5.- Fecha y Hora de certificación
                    resultado.SelloCfdi          = resultadoTimbre.SelloCFDI;           //6.- Sello del cfdi
                    resultado.SelloSat           = resultadoTimbre.SelloSAT;            //7.- Sello del SAT
                    resultado.CadenaTimbre       = resultadoTimbre.CadenaTimbre;        //8.- Cadena original de complemento de certificación
                    resultado.Xml      = resultadoTimbre.Xml;
                    resultado.CbbBytes = resultadoTimbre.CodigoBidimensional;
                }

                return(resultado);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw e.GetBaseException();
            }
        }