public CFDIXmlTextWriter(Comprobante comprobante, System.IO.Stream stream, Encoding encoding) {
            this.comprobante = comprobante;
            this.fileName = null;
            this.encoding = encoding;

            this.writer = new System.Xml.XmlTextWriter(stream, System.Text.Encoding.UTF8);
        }
        public CFDIXmlTextWriter(Comprobante comprobante, string fileName, Encoding encoding) {
            this.comprobante = comprobante;
            this.fileName = fileName;
            this.encoding = encoding;

            this.writer = new System.Xml.XmlTextWriter(fileName, System.Text.Encoding.UTF8);
        }
        public ICancelaResponse CancelaCFDI(Comprobante comprobante, string user, string password, string rfc, string[] uuid, byte[] pfx, string pfxPassword)
        {
            string invoiceFileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + comprobante.PublicKey.ToString("N");
            //byte[] sendFileBytes;
            byte[] responseFileBytes;

            CloudStorageAccount account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["AzureDefaultStorageConnectionString"]);
            CloudBlobClient client = account.CreateCloudBlobClient();
            CloudBlobContainer container = client.GetContainerReference(ConfigurationManager.AppSettings["AzureDefaultStorage"]);

            try {

                ICFDIService webService = CFDiServiceFactory.Create();
                ICancelaResponse response = webService.CancelaCFDI(user, password, rfc, uuid, pfx, pfxPassword);
                // response.XmlResponse

                CloudBlockBlob blob = container.GetBlockBlobReference(invoiceFileName + "_cancelado.txt");
                blob.UploadText(response.XmlResponse, System.Text.Encoding.UTF8);

                return response;
            }
            catch (Exception ex) {
                CloudBlockBlob blob2 = container.GetBlockBlobReference(invoiceFileName + "_exception.txt");
                //zipMs.Position = 0;
                blob2.UploadText(ex.ToString());
                blob2.Properties.ContentType = "text/plain";
                blob2.SetMetadata();
                blob2.SetProperties();

                throw;
            }
        }
        public ComprobanteCreateViewModel(Comprobante comprobante) {
            if (comprobante == null)
                throw new ArgumentNullException("comprobante");

            if (comprobante.Emisor != null) {
                this.Emisor = new EmisorDetailViewModel(comprobante.Emisor);
            }

            if (comprobante.Receptor != null) {
                this.Receptor = new ReceptorDetailsViewModel(comprobante.Receptor);
            }

            if (comprobante.Conceptos != null && comprobante.Conceptos.Count > 0) {
                this.Conceptos = new List<ConceptoViewModel>();
                foreach (Concepto concepto in comprobante.Conceptos) {
                    this.Conceptos.Add(new ConceptoViewModel(concepto));
                }
            }

            if (comprobante.Impuestos.Traslados != null && comprobante.Impuestos.Traslados.Count > 0)
            {
                this.Traslados = new List<TrasladoViewModel>();
                foreach (Traslado traslado in comprobante.Impuestos.Traslados)
                {
                    this.Traslados.Add(new TrasladoViewModel(traslado));
                }
            }

            if (comprobante.Impuestos.Retenciones != null && comprobante.Impuestos.Retenciones.Count > 0)
            {
                this.Retenciones = new List<RetencionViewModel>();
                foreach (Retencion retencion in comprobante.Impuestos.Retenciones)
                {
                    this.Retenciones.Add(new RetencionViewModel(retencion));
                }
            }

            this.EmisorId = comprobante.EmisorId;
            this.CertificadoId = comprobante.CertificadoId;
            this.ReceptorId = comprobante.ReceptorId;

            this.MetodoDePago = comprobante.MetodoDePago;
            this.LugarExpedicion = comprobante.LugarExpedicion;
            this.FormaDePago = comprobante.FormaDePago;

            this.Serie = comprobante.Serie;
            this.Folio = comprobante.Folio;

            this.TipoCambio = comprobante.TipoCambio;
            this.Moneda = comprobante.Moneda;

            this.Banco = comprobante.ExtendedStringValue1;

            this.SubTotal = comprobante.SubTotal;
            this.Total = comprobante.Total;

            this.TotalImpuestosRetenidos = comprobante.Impuestos.TotalImpuestosRetenidos;
            this.TotalImpuestosTrasladados = comprobante.Impuestos.TotalImpuestosTrasladados;
        }
        public ActionResult Upload(ComprobanteUploadViewModel model) {
            string comprobanteId = "";
            if (ModelState.IsValid) {



                if (model.ComprobanteArchivo == null || model.ComprobanteArchivo.ContentLength == 0) {
                    return View();
                }
                try {

                    Comprobante comprobante = new Comprobante();
                    Certificado certificado = new Certificado();

                    if (model.ComprobanteArchivo != null) {
                        // MemoryStream target = new MemoryStream();

                        System.Xml.XmlTextReader xmlReader = new System.Xml.XmlTextReader(model.ComprobanteArchivo.InputStream);

                        while (xmlReader.Read()) {
                            if (xmlReader.NodeType == System.Xml.XmlNodeType.Element) {

                                if ("xml".Equals(xmlReader.Name)) {

                                }
                                else if ("cfdi:Comprobante".Equals(xmlReader.Name)) {
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "version":
                                                comprobante.Version = xmlReader.Value;
                                                break;
                                            case "serie":
                                                comprobante.Serie = xmlReader.Value;
                                                break;
                                            case "folio":
                                                comprobante.Folio = xmlReader.Value;
                                                break;
                                            case "fecha":
                                                comprobante.Fecha = DateTime.Parse(xmlReader.Value);
                                                break;
                                            case "sello":
                                                comprobante.Sello = xmlReader.Value;
                                                break;
                                            case "noAprobacion":
                                                comprobante.NoAprobacion = xmlReader.Value;
                                                break;
                                            case "anoAprobacion":
                                                comprobante.AnoAprobacion = xmlReader.Value;
                                                break;
                                            case "formaDePago":
                                                comprobante.FormaDePago = xmlReader.Value;
                                                break;
                                            case "noCertificado":
                                                certificado.NumSerie = xmlReader.Value;
                                                //comprobante.LugarExpedicion = xmlReader.Value;
                                                comprobante.HasNoCertificado = true;
                                                break;
                                            case "certificado":
                                                //comprobante.LugarExpedicion = xmlReader.Value;
                                                certificado.CertificadoBase64 = xmlReader.Value;
                                                comprobante.HasCertificado = true;
                                                break;
                                            case "condicionesDePago":
                                                comprobante.CondicionesDePago = xmlReader.Value;
                                                break;
                                            case "subTotal":
                                                comprobante.SubTotal = decimal.Parse(xmlReader.Value);
                                                break;
                                            case "descuento":
                                                comprobante.Descuento = decimal.Parse(xmlReader.Value);
                                                break;
                                            case "motivoDescuento":
                                                comprobante.MotivoDescuento = xmlReader.Value;
                                                break;
                                            case "TipoCambio":
                                                comprobante.TipoCambio = xmlReader.Value;
                                                break;
                                            case "Moneda":
                                                comprobante.Moneda = xmlReader.Value;
                                                break;
                                            case "total":
                                                comprobante.Total = decimal.Parse(xmlReader.Value);
                                                break;
                                            case "tipoDeComprobante":
                                                comprobante.TipoDeComprobante = xmlReader.Value;
                                                break;
                                            case "metodoDePago":
                                                comprobante.MetodoDePago = xmlReader.Value;
                                                break;
                                            case "LugarExpedicion":
                                                comprobante.LugarExpedicion = xmlReader.Value;
                                                break;
                                            case "NumCtaPago":
                                                comprobante.NumCtaPago = xmlReader.Value;
                                                break;
                                            case "SerieFolioFiscalOrig":
                                                comprobante.SerieFolioFiscalOrig = xmlReader.Value;
                                                break;
                                            case "FechaFolioFiscalOrig":
                                                comprobante.FechaFolioFiscalOrig = DateTime.Parse(xmlReader.Value);
                                                break;
                                            case "MontoFolioFiscalOrig":
                                                comprobante.MontoFolioFiscalOrig = decimal.Parse(xmlReader.Value);
                                                break;

                                            case "xmlns:cfdi":
                                            case "xmlns:xsi":
                                            case "xsi:schemaLocation":
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Comprobante.");
                                        }
                                    }


                                }

                                else if ("cfdi:Emisor".Equals(xmlReader.Name)) {
                                    comprobante.Emisor = new Emisor();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "rfc":
                                                comprobante.Emisor.RFC = xmlReader.Value;
                                                break;
                                            case "nombre":
                                                comprobante.Emisor.Nombre = xmlReader.Value;
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Emisor.");
                                        }
                                    }
                                }

                                else if ("cfdi:DomicilioFiscal".Equals(xmlReader.Name)) {
                                    comprobante.Emisor.DomicilioFiscal = new UbicacionFiscal();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "calle":
                                                comprobante.Emisor.DomicilioFiscal.Calle = xmlReader.Value;
                                                break;
                                            case "noExterior":
                                                comprobante.Emisor.DomicilioFiscal.NoExterior = xmlReader.Value;
                                                break;
                                            case "noInterior":
                                                comprobante.Emisor.DomicilioFiscal.NoInterior = xmlReader.Value;
                                                break;
                                            case "colonia":
                                                comprobante.Emisor.DomicilioFiscal.Colonia = xmlReader.Value;
                                                break;
                                            case "localidad":
                                                comprobante.Emisor.DomicilioFiscal.Localidad = xmlReader.Value;
                                                break;
                                            case "referencia":
                                                comprobante.Emisor.DomicilioFiscal.Referencia = xmlReader.Value;
                                                break;
                                            case "municipio":
                                                comprobante.Emisor.DomicilioFiscal.Municipio = xmlReader.Value;
                                                break;
                                            case "estado":
                                                comprobante.Emisor.DomicilioFiscal.Estado = xmlReader.Value;
                                                break;
                                            case "pais":
                                                comprobante.Emisor.DomicilioFiscal.Pais = xmlReader.Value;
                                                break;
                                            case "codigoPostal":
                                                comprobante.Emisor.DomicilioFiscal.CodigoPostal = xmlReader.Value;
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:DomicilioFiscal.");
                                        }
                                    }
                                }

                                else if ("cfdi:RegimenFiscal".Equals(xmlReader.Name)) {
                                    if (comprobante.Emisor.RegimenFiscal == null)
                                        comprobante.Emisor.RegimenFiscal = new List<RegimenFiscal>();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "Regimen":
                                                RegimenFiscal regimen = new RegimenFiscal();
                                                regimen.Regimen = xmlReader.Value;
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:RegimenFiscal.");
                                        }
                                    }
                                }

                                else if ("cfdi:Receptor".Equals(xmlReader.Name)) {
                                    comprobante.Receptor = new Receptor();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "rfc":
                                                comprobante.Receptor.RFC = xmlReader.Value;
                                                break;
                                            case "nombre":
                                                comprobante.Receptor.Nombre = xmlReader.Value;
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Receptor.");
                                        }
                                    }
                                }

                                else if ("cfdi:Domicilio".Equals(xmlReader.Name)) {
                                    comprobante.Receptor.Domicilio = new Ubicacion();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "calle":
                                                comprobante.Receptor.Domicilio.Calle = xmlReader.Value;
                                                break;
                                            case "noExterior":
                                                comprobante.Receptor.Domicilio.NoExterior = xmlReader.Value;
                                                break;
                                            case "noInterior":
                                                comprobante.Receptor.Domicilio.NoInterior = xmlReader.Value;
                                                break;
                                            case "colonia":
                                                comprobante.Receptor.Domicilio.Colonia = xmlReader.Value;
                                                break;
                                            case "localidad":
                                                comprobante.Receptor.Domicilio.Localidad = xmlReader.Value;
                                                break;
                                            case "referencia":
                                                comprobante.Receptor.Domicilio.Referencia = xmlReader.Value;
                                                break;
                                            case "municipio":
                                                comprobante.Receptor.Domicilio.Municipio = xmlReader.Value;
                                                break;
                                            case "estado":
                                                comprobante.Receptor.Domicilio.Estado = xmlReader.Value;
                                                break;
                                            case "pais":
                                                comprobante.Receptor.Domicilio.Pais = xmlReader.Value;
                                                break;
                                            case "codigoPostal":
                                                comprobante.Receptor.Domicilio.CodigoPostal = xmlReader.Value;
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Domicilio.");
                                        }
                                    }
                                }

                                else if ("cfdi:Conceptos".Equals(xmlReader.Name)) {
                                    comprobante.Conceptos = new List<Concepto>();
                                }

                                else if ("cfdi:Concepto".Equals(xmlReader.Name)) {
                                    Concepto concepto = new Concepto();
                                    concepto.PublicKey = Guid.NewGuid();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "cantidad":
                                                concepto.Cantidad = decimal.Parse(xmlReader.Value);
                                                break;
                                            case "unidad":
                                                concepto.Unidad = xmlReader.Value;
                                                break;
                                            case "noIdentificacion":
                                                concepto.NoIdentificacion = xmlReader.Value;
                                                break;
                                            case "descripcion":
                                                concepto.Descripcion = xmlReader.Value;
                                                break;
                                            case "valorUnitario":
                                                concepto.ValorUnitario = decimal.Parse(xmlReader.Value);
                                                break;
                                            case "importe":
                                                concepto.Importe = decimal.Parse(xmlReader.Value);
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Domicilio.");
                                        }
                                    }
                                    concepto.Ordinal = comprobante.Conceptos.Count + 1;
                                    comprobante.Conceptos.Add(concepto);
                                }

                                else if ("cfdi:Impuestos".Equals(xmlReader.Name)) {
                                    comprobante.Impuestos = new Impuestos();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "totalImpuestosRetenidos":
                                                comprobante.Impuestos.TotalImpuestosRetenidos = decimal.Parse(xmlReader.Value);
                                                break;
                                            case "totalImpuestosTrasladados":
                                                comprobante.Impuestos.TotalImpuestosTrasladados = decimal.Parse(xmlReader.Value);
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Impuestos.");
                                        }
                                    }
                                }

                                else if ("cfdi:Traslados".Equals(xmlReader.Name)) {
                                    comprobante.Impuestos.Traslados = new List<Traslado>();
                                }

                                else if ("cfdi:Traslado".Equals(xmlReader.Name)) {
                                    Traslado traslado = new Traslado();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "impuesto":
                                                traslado.Impuesto = xmlReader.Value;
                                                break;
                                            case "tasa":
                                                traslado.Tasa = decimal.Parse(xmlReader.Value);
                                                break;
                                            case "importe":
                                                traslado.Importe = decimal.Parse(xmlReader.Value);
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Impuestos.");
                                        }
                                    }
                                    comprobante.Impuestos.Traslados.Add(traslado);
                                }

                                else if ("cfdi:Retenciones".Equals(xmlReader.Name)) {
                                    comprobante.Impuestos.Retenciones = new List<Retencion>();
                                }

                                else if ("cfdi:Retencion".Equals(xmlReader.Name)) {
                                    Retencion retencion = new Retencion();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "impuesto":
                                                retencion.Impuesto = xmlReader.Value;
                                                break;
                                            case "importe":
                                                retencion.Importe = decimal.Parse(xmlReader.Value);
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + "is not a valid attribute for cfdi:Retencion.");
                                        }
                                    }
                                    comprobante.Impuestos.Retenciones.Add(retencion);
                                }

                                else if ("cfdi:Complemento".Equals(xmlReader.Name)) {
                                    comprobante.Complementos = new List<Complemento>();
                                }

                                else if ("tfd:TimbreFiscalDigital".Equals(xmlReader.Name)) {
                                    TimbreFiscalDigital timbre = new TimbreFiscalDigital();
                                    while (xmlReader.MoveToNextAttribute()) {
                                        switch (xmlReader.Name) {
                                            case "version":
                                                timbre.Version = xmlReader.Value;
                                                break;
                                            case "UUID":
                                                timbre.UUID = xmlReader.Value;
                                                break;
                                            case "FechaTimbrado":
                                                timbre.FechaTimbrado = DateTime.Parse(xmlReader.Value);
                                                break;
                                            case "selloCFD":
                                                timbre.SelloCFD = xmlReader.Value;
                                                break;
                                            case "noCertificadoSAT":
                                                timbre.NoCertificadoSAT = xmlReader.Value;
                                                break;
                                            case "selloSAT":
                                                timbre.SelloSAT = xmlReader.Value;
                                                break;
                                            case "xmlns:tfd":
                                            case "xsi:schemaLocation":
                                                break;
                                            default:
                                                throw new Exception(xmlReader.Name + " is not a valid attribute for cfdi:TimbreFiscalDigital.");
                                        }
                                    }
                                    comprobante.Complementos.Add(timbre);
                                }

                                else {
                                    xmlReader.NodeType.ToString();
                                    xmlReader.Name.ToString();
                                }
                                //xmlReader.NodeType.ToString();
                            }
                        }

                        //xmlReader.Dispose();
                        //xmlReader.Close();

                        model.ComprobanteArchivo.InputStream.Position = 0;
                        //model.ComprobanteArchivo.InputStream.Position = 0;

                        //model.ComprobanteArchivo.InputStream.CopyTo(target);
                        //Byte[] data = target.ToArray();

                        if (certificado != null) {
                            if (!string.IsNullOrEmpty(certificado.NumSerie)) {
                                certificado = DBContext.Certificados.Where(c => c.NumSerie == certificado.NumSerie).SingleOrDefault();
                                comprobante.Certificado = certificado;
                            }
                        }

                        if (comprobante.Emisor != null) {
                            //Emisor emisor = DBContext.Emisores.Where(e => 
                            //    (e.RFC == comprobante.Emisor.RFC)
                            //    && (e.Nombre == comprobante.Emisor.Nombre)                                
                            //    && (e.Status == "A")
                            //    ).SingleOrDefault();

                            List<Emisor> emisores = DBContext.Emisores.Where(e =>
                                (e.RFC == comprobante.Emisor.RFC)
                                && (e.Nombre == comprobante.Emisor.Nombre)
                                ).ToList();

                            if (emisores != null && emisores.Count > 0) {
                                foreach (Emisor emisor in emisores) {

                                    if ((emisor.DomicilioFiscal != null && comprobante.Emisor.DomicilioFiscal != null)
                                        && (emisor.DomicilioFiscal.Calle == comprobante.Emisor.DomicilioFiscal.Calle)
                                        && (emisor.DomicilioFiscal.NoExterior == comprobante.Emisor.DomicilioFiscal.NoExterior)
                                        && (emisor.DomicilioFiscal.NoInterior == comprobante.Emisor.DomicilioFiscal.NoInterior)
                                        && (emisor.DomicilioFiscal.Colonia == comprobante.Emisor.DomicilioFiscal.Colonia)
                                        && (emisor.DomicilioFiscal.Referencia == comprobante.Emisor.DomicilioFiscal.Referencia)
                                        && (emisor.DomicilioFiscal.Localidad == comprobante.Emisor.DomicilioFiscal.Localidad)
                                        && (emisor.DomicilioFiscal.Municipio == comprobante.Emisor.DomicilioFiscal.Municipio)
                                        && (emisor.DomicilioFiscal.Estado == comprobante.Emisor.DomicilioFiscal.Estado)
                                        && (emisor.DomicilioFiscal.CodigoPostal == comprobante.Emisor.DomicilioFiscal.CodigoPostal)
                                        && (emisor.DomicilioFiscal.Pais == comprobante.Emisor.DomicilioFiscal.Pais)
                                        ) {

                                        //if (receptor != null) {
                                        comprobante.Emisor = emisor;
                                        comprobante.EmisorId = emisor.EmisorId;
                                    }
                                }
                                if (comprobante.EmisorId == null) {
                                    // The address has changed, create a new one and inactive the oldone

                                    foreach (Emisor emisor in emisores) {
                                        emisor.Status = "I";
                                    }

                                    comprobante.Emisor.Status = "A";

                                }

                            }
                            else {
                                comprobante.Emisor.Status = "A";
                            }
                        }

                        if (comprobante.Receptor != null) {
                            //Receptor receptor = DBContext.Receptores.Where(r =>
                            //    (r.RFC == comprobante.Receptor.RFC)
                            //    && (r.Nombre == comprobante.Receptor.Nombre)
                            //    && (r.Status == "A")
                            //    ).SingleOrDefault();

                            List<Receptor> receptores = DBContext.Receptores.Where(r =>
                                (r.RFC == comprobante.Receptor.RFC)
                                && (r.Nombre == comprobante.Receptor.Nombre)
                                ).ToList();

                            if (receptores != null && receptores.Count > 0) {
                                foreach (Receptor receptor in receptores) {

                                    if ((receptor.Domicilio != null && comprobante.Receptor.Domicilio != null)
                                        && (receptor.Domicilio.Calle == comprobante.Receptor.Domicilio.Calle)
                                        && (receptor.Domicilio.NoExterior == comprobante.Receptor.Domicilio.NoExterior)
                                        && (receptor.Domicilio.NoInterior == comprobante.Receptor.Domicilio.NoInterior)
                                        && (receptor.Domicilio.Colonia == comprobante.Receptor.Domicilio.Colonia)
                                        && (receptor.Domicilio.Referencia == comprobante.Receptor.Domicilio.Referencia)
                                        && (receptor.Domicilio.Localidad == comprobante.Receptor.Domicilio.Localidad)
                                        && (receptor.Domicilio.Municipio == comprobante.Receptor.Domicilio.Municipio)
                                        && (receptor.Domicilio.Estado == comprobante.Receptor.Domicilio.Estado)
                                        && (receptor.Domicilio.CodigoPostal == comprobante.Receptor.Domicilio.CodigoPostal)
                                        && (receptor.Domicilio.Pais == comprobante.Receptor.Domicilio.Pais)
                                        ) {

                                        //if (receptor != null) {
                                        comprobante.Receptor = receptor;
                                        comprobante.ReceptorId = receptor.ReceptorId;
                                    }
                                }
                                if (comprobante.ReceptorId == null) {
                                    // The address has changed, create a new one and inactive the oldone

                                    foreach (Receptor receptor in receptores) {
                                        receptor.Status = "I";
                                    }

                                    comprobante.Receptor.Status = "A";

                                }
                            }
                            else {
                                comprobante.Receptor.Status = "A";
                            }

                            //if (receptor != null) {
                            //    comprobante.Receptor = receptor;
                            //    comprobante.ReceptorId = receptor.ReceptorId;
                            //}
                            //else {

                            //}
                        }

                        comprobante.GeneratedCadenaOriginal = comprobante.GetCadenaOriginal();

                        if (model.ComprobantePDFArchivo != null && model.ComprobantePDFArchivo.ContentLength > 0) {
                            comprobante.GeneratedXmlUrl = string.Format(@"https://sistrategiacfdi1.blob.core.windows.net/{0}/{1}.xml",
                                comprobante.Emisor.PublicKey.ToString("N"),
                                comprobante.PublicKey.ToString("N"));
                            comprobante.GeneratedPDFUrl = string.Format(@"https://sistrategiacfdi1.blob.core.windows.net/{0}/{1}.pdf",
                                comprobante.Emisor.PublicKey.ToString("N"),
                                comprobante.PublicKey.ToString("N"));
                            //comprobante.GeneratedPDFUrl
                            //comprobante.ExtendedIntValue1 = model.NoOrden;
                            //comprobante.ExtendedIntValue2 = model.NoCliente;
                        }

                        comprobante.ExtendedIntValue1 = DBContext.Comprobantes.Max(c => c.ExtendedIntValue1) + 1; // DBContext.Comprobantes.Count() + 1;
                        if (comprobante.ReceptorId != null)
                            comprobante.ExtendedIntValue2 = comprobante.ReceptorId;
                        else
                            comprobante.ExtendedIntValue2 = DBContext.Receptores.Count() + 1;

                        comprobante.ViewTemplate = DBContext.ViewTemplates.Find(2);
                        comprobante.ViewTemplateId = comprobante.ViewTemplate.ViewTemplateId;

                        comprobante.Status = "A";

                        comprobanteId = comprobante.PublicKey.ToString("N");
                        DBContext.Comprobantes.Add(comprobante);
                        DBContext.SaveChanges();

                        if (model.ComprobantePDFArchivo != null && model.ComprobantePDFArchivo.ContentLength > 0) {
                            CloudStorageMananger manager = new CloudStorageMananger();
                            manager.UploadFromStream(ConfigurationManager.AppSettings["AzureAccountName"],
                                ConfigurationManager.AppSettings["AzureAccountKey"],
                                comprobante.Emisor.PublicKey.ToString("N"),
                                comprobante.PublicKey.ToString("N") + ".xml",
                                model.ComprobanteArchivo.FileName,
                                model.ComprobanteArchivo.ContentType,
                                model.ComprobanteArchivo.InputStream);

                            manager.UploadFromStream(ConfigurationManager.AppSettings["AzureAccountName"],
                                ConfigurationManager.AppSettings["AzureAccountKey"],
                                comprobante.Emisor.PublicKey.ToString("N"),
                                comprobante.PublicKey.ToString("N") + ".pdf",
                                model.ComprobantePDFArchivo.FileName,
                                model.ComprobantePDFArchivo.ContentType,
                                model.ComprobantePDFArchivo.InputStream);
                        }
                    }
                }
                catch (Exception ex) {
                    //log.Error(ex, "Error upload photo blob to storage");
                    ex.ToString();
                }
            }
            return RedirectToAction("Details", "Comprobante", new { id = comprobanteId });
        }
        public JsonResult Create(ComprobanteCreateViewModel model) {
            try {
                if (String.IsNullOrEmpty(model.LugarExpedicion))
                    throw new ApplicationException("¡Ingrese el lugar de expedición!");
                else if (model.EmisorId <= 0)
                    throw new ApplicationException("¡Ingrese el emisor!");
                else if (model.ReceptorId <= 0)
                    throw new ApplicationException("¡Ingrese el receptor!");
                else if (model.CertificadoId <= 0)
                    throw new ApplicationException("¡Ingrese el certificado!");
                else if (String.IsNullOrEmpty(model.FormaDePago))
                    throw new ApplicationException("¡Ingrese la forma de pago!");
                else if (String.IsNullOrEmpty(model.MetodoDePago))
                    throw new ApplicationException("¡Ingrese el método de pago!");
                else if ((model.MetodoDePago != "EFECTIVO" && model.MetodoDePago != "NO IDENTIFICADO") && (model.NumCtaPago == null || (model.NumCtaPago.Count() > 6 || model.NumCtaPago.Count() < 4)))
                    throw new ApplicationException("¡El valor de NumCtaPago debe contener entre 4 hasta 6 caracteres!");
                else if ((model.MetodoDePago != "EFECTIVO" && model.MetodoDePago != "NO IDENTIFICADO") && (string.IsNullOrEmpty(model.Banco)))
                    throw new ApplicationException("¡Ingrese el banco!");
                else if ((model.Conceptos != null || model.Conceptos.Count > 0)
                    && model.Conceptos.All(x => x.Cantidad < 0m || x.Unidad == null || x.Descripcion == null || x.ValorUnitario < 0m))
                    throw new ApplicationException("¡Ingrese al menos un concepto!");
                else if (model.SubTotal < 0m)
                    throw new ApplicationException("¡SubTotal no válido!");
                else if (model.TotalImpuestosTrasladados < 0m)
                    throw new ApplicationException("¡Total Impuestos Trasladados no válido!");
                else if (model.TotalImpuestosRetenidos < 0m)
                    throw new ApplicationException("¡Total Impuestos Retenidos no válido!");
                else if (model.Total < 0m)
                    throw new ApplicationException("¡Total no válido!");
                else {

                    var comprobante = new Comprobante();

                    comprobante.EmisorId = model.EmisorId;
                    comprobante.Emisor = DBContext.Emisores.Find(model.EmisorId); // .Where(e => e.PublicKey == publicKey).SingleOrDefault();
                    comprobante.ReceptorId = model.ReceptorId;
                    comprobante.Receptor = DBContext.Receptores.Find(model.ReceptorId); // .Where(e => e.PublicKey == publicKey).SingleOrDefault();
                    comprobante.Serie = model.Serie;
                    comprobante.Folio = model.Folio;
                    comprobante.Fecha = DateTime.Now + SATManager.GetCFDIServiceTimeSpan();
                    comprobante.FormaDePago = model.FormaDePago;
                    comprobante.SubTotal = model.SubTotal;
                    comprobante.Total = model.Total;

                    //comprobante.NoCertificado;
                    //comprobante.Certificado;
                    comprobante.TipoDeComprobante = "ingreso";

                    comprobante.FormaDePago = model.FormaDePago;
                    comprobante.MetodoDePago = model.MetodoDePago;
                    comprobante.LugarExpedicion = model.LugarExpedicion;
                    comprobante.TipoCambio = model.TipoCambio;
                    comprobante.Moneda = model.Moneda;
                    comprobante.NumCtaPago = model.NumCtaPago;
                    comprobante.ExtendedStringValue1 = model.Banco;
                    comprobante.Moneda = model.Moneda;

                    comprobante.Conceptos = new List<Concepto>();

                    foreach (var modelConcepto in model.Conceptos) {
                        if (!string.IsNullOrEmpty(modelConcepto.Descripcion)) {
                            comprobante.Conceptos.Add(new Concepto {
                                Cantidad = modelConcepto.Cantidad,
                                Unidad = modelConcepto.Unidad,
                                NoIdentificacion = modelConcepto.NoIdentificacion,
                                Descripcion = modelConcepto.Descripcion,
                                ValorUnitario = modelConcepto.ValorUnitario,
                                Importe = modelConcepto.Importe,
                                PublicKey = Guid.NewGuid(),
                                Ordinal = modelConcepto.Ordinal
                            });
                        }
                    }

                    comprobante.Impuestos = new Impuestos();
                    comprobante.Impuestos.Traslados = new List<Traslado>();

                    foreach (var modelTraslado in model.Traslados) {
                        if (modelTraslado.Tasa > 0 && modelTraslado.Importe > 0) {
                            comprobante.Impuestos.Traslados.Add(new Traslado {
                                Importe = modelTraslado.Importe,
                                Impuesto = modelTraslado.Impuesto,
                                Tasa = modelTraslado.Tasa,
                            });
                        }
                    }

                    comprobante.Impuestos.Retenciones = new List<Retencion>();
                    foreach (var modelRetencion in model.Retenciones) {
                        if (modelRetencion.Importe > 0) {
                            comprobante.Impuestos.Retenciones.Add(new Retencion {
                                Importe = modelRetencion.Importe,
                                Impuesto = modelRetencion.Impuesto,
                            });
                        }
                    }

                    if (model.TotalImpuestosRetenidos > 0)
                        comprobante.Impuestos.TotalImpuestosRetenidos = model.TotalImpuestosRetenidos;

                    if (model.TotalImpuestosTrasladados > 0)
                        comprobante.Impuestos.TotalImpuestosTrasladados = model.TotalImpuestosTrasladados;

                    comprobante.PublicKey = Guid.NewGuid();

                    Certificado certificado = DBContext.Certificados.Find(model.CertificadoId);

                    if (certificado != null) {
                        // comprobante.NoCertificado = certificado.NumSerie;
                        // comprobante.Certificado = certificado.CertificadoBase64;
                        comprobante.CertificadoId = certificado.CertificadoId;
                        comprobante.Certificado = certificado;
                        comprobante.HasNoCertificado = true;
                        comprobante.HasCertificado = true;
                    }

                    string cadenaOriginal = comprobante.GetCadenaOriginal();
                    comprobante.Sello = certificado.GetSello(cadenaOriginal);
                    comprobante.Status = "P";
                    DBContext.Comprobantes.Add(comprobante);
                    DBContext.SaveChanges();

                    TempData["success"] = "Se ha creado el comprobante correctamente";
                    var data = new {
                        error = false,
                        errorMsg = "",
                        comprobanteId = comprobante.PublicKey
                    };
                    return Json(data);
                }
            }
            catch (Exception ex) {
                var data = new {
                    error = true,
                    errorMsg = ex.Message.ToString()
                };
                return Json(data);
            }
        }
Beispiel #7
0
        public bool GetCFDI(string user, string password, CFDI.Comprobante comprobante)
        {
            //throw new NotImplementedException();

            string invoiceFileName = DateTime.Now.ToString("yyyyMMddHHmmss_" + comprobante.PublicKey.ToString("N"));

            byte[] sendFileBytes;
            byte[] responseFileBytes;


            CloudStorageAccount account   = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["AzureDefaultStorageConnectionString"]);
            CloudBlobClient     client    = account.CreateCloudBlobClient();
            CloudBlobContainer  container = client.GetContainerReference(ConfigurationManager.AppSettings["AzureDefaultStorage"]);

            try {
                using (MemoryStream ms = new MemoryStream()) {
                    using (MemoryStream zipMs = new MemoryStream()) {
                        CFDIXmlTextWriter writer =
                            new CFDIXmlTextWriter(comprobante, ms, System.Text.Encoding.UTF8);
                        writer.WriteXml();
                        ms.Position = 0;

                        using (ZipArchive zip = new ZipArchive(zipMs, ZipArchiveMode.Create, true)) {
                            var entry = zip.CreateEntry(invoiceFileName + "_send.xml");
                            using (Stream s = entry.Open()) {
                                ms.CopyTo(s);
                            }
                            zipMs.Flush();
                        } // zip.Dispose() => Close();


                        // container.CreateIfNotExists();
                        CloudBlockBlob blob = container.GetBlockBlobReference(invoiceFileName + "_send.zip");
                        zipMs.Position = 0;

                        blob.UploadFromStream(zipMs);
                        blob.Properties.ContentType = "application/x-zip-compressed";
                        blob.SetMetadata();
                        blob.SetProperties();

                        zipMs.Position = 0;
                        sendFileBytes  = zipMs.ToArray();
                    } // zipMs.Dispose() => Close();
                }     // ms.Dispose() => Close();

                //CFDI.EDICOM.TestCFDI.CFDiService webService = new CFDI.EDICOM.TestCFDI.CFDiService();
                //responseFileBytes = webService.getCfdiTest(user, password, sendFileBytes);
                ICFDIService webService = CFDiServiceFactory.Create();
                responseFileBytes = webService.GetCFDI(user, password, sendFileBytes);

                CloudBlockBlob blob2 = container.GetBlockBlobReference(invoiceFileName + "_response.zip");
                //zipMs.Position = 0;

                blob2.UploadFromByteArray(responseFileBytes, 0, responseFileBytes.Length); // .UploadFromStream(zipMs);
                blob2.Properties.ContentType = "application/x-zip-compressed";
                blob2.SetMetadata();
                blob2.SetProperties();

                using (var responseStream = new MemoryStream(responseFileBytes)) {
                    using (var archive = new ZipArchive(responseStream, ZipArchiveMode.Read, true)) {
                        var fileInArchive = archive.Entries[0]; //
                        using (var entryStream = fileInArchive.Open()) {
                            using (var reader = new StreamReader(entryStream)) {
                                string output = reader.ReadToEnd();


                                System.Xml.XmlDocument invoice = new System.Xml.XmlDocument();
                                invoice.LoadXml(output);

                                System.Xml.XmlNamespaceManager nsmgr = new System.Xml.XmlNamespaceManager(invoice.NameTable);
                                nsmgr.AddNamespace("cfdi", "http://www.sat.gob.mx/cfd/3");
                                nsmgr.AddNamespace("tfd", "http://www.sat.gob.mx/TimbreFiscalDigital");
                                System.Xml.XmlNode timbre = invoice.SelectSingleNode("//tfd:TimbreFiscalDigital", nsmgr);

                                TimbreFiscalDigital complemento = new TimbreFiscalDigital();

                                complemento.Version          = timbre.Attributes.GetNamedItem("version").Value.ToString();
                                complemento.UUID             = timbre.Attributes.GetNamedItem("UUID").Value.ToString();
                                complemento.FechaTimbrado    = DateTime.Parse(timbre.Attributes.GetNamedItem("FechaTimbrado").Value);
                                complemento.SelloCFD         = timbre.Attributes.GetNamedItem("selloCFD").Value.ToString();
                                complemento.NoCertificadoSAT = timbre.Attributes.GetNamedItem("noCertificadoSAT").Value.ToString();
                                complemento.SelloSAT         = timbre.Attributes.GetNamedItem("selloSAT").Value.ToString();

                                if (comprobante.Complementos == null)
                                {
                                    comprobante.Complementos = new List <Complemento>();
                                }
                                comprobante.Complementos.Add(complemento);
                                //Complemento complemento = new Complemento();
                                //complemento.


                                //           //    Sistrategia.Server.SAT.CFDI.Comprobante comprobante2 = Sistrategia.Server.SAT.SATManager.GetComprobante(Guid.Parse(post["comprobanteId"]));
                                //           //    comprobante2.Complemento = new Sistrategia.Server.SAT.CFDI.ComprobanteComplemento();
                                //           //    comprobante2.Complemento.TimbreFiscalDigitalSpecified = true;
                                //           //    comprobante2.Complemento.TimbreFiscalDigital = new Sistrategia.Server.SAT.CFDI.ComprobanteTimbre();
                                //           //    comprobante2.Complemento.TimbreFiscalDigital.SatTimbreId = Guid.NewGuid();
                                //           //    comprobante2.Complemento.TimbreFiscalDigital.Version = timbre.Attributes.GetNamedItem("version").Value.ToString();
                                //           //    comprobante2.Complemento.TimbreFiscalDigital.UUID = timbre.Attributes.GetNamedItem("UUID").Value.ToString();
                                //           //    comprobante2.Complemento.TimbreFiscalDigital.FechaTimbrado = DateTime.Parse(timbre.Attributes.GetNamedItem("FechaTimbrado").Value);
                                //           //    comprobante2.Complemento.TimbreFiscalDigital.SelloCFD = timbre.Attributes.GetNamedItem("selloCFD").Value.ToString();
                                //           //    comprobante2.Complemento.TimbreFiscalDigital.NoCertificadoSAT = timbre.Attributes.GetNamedItem("noCertificadoSAT").Value.ToString();
                                //           //    comprobante2.Complemento.TimbreFiscalDigital.SelloSAT = timbre.Attributes.GetNamedItem("selloSAT").Value.ToString();

                                // entryStream.Position = 0;
                                //  entryStream.Position



                                // SAVE final xml:
                                Sistrategia.SAT.CFDiWebSite.CloudStorage.CloudStorageMananger manager =
                                    new Sistrategia.SAT.CFDiWebSite.CloudStorage.CloudStorageMananger();
                                //manager.UploadFromStream(ConfigurationManager.AppSettings["AzureAccountName"],
                                manager.UploadFromString(ConfigurationManager.AppSettings["AzureAccountName"],
                                                         ConfigurationManager.AppSettings["AzureAccountKey"],
                                                         comprobante.Emisor.PublicKey.ToString("N"),
                                                         comprobante.PublicKey.ToString("N") + ".xml",
                                                         comprobante.Serie + comprobante.Folio + ".xml", //model.ComprobanteArchivo.FileName,
                                                         "text/xml",                                     //model.ComprobanteArchivo.ContentType,
                                                         output);                                        // model.ComprobanteArchivo.InputStream);

                                comprobante.GeneratedCadenaOriginal = comprobante.GetCadenaOriginal();
                                comprobante.GeneratedXmlUrl         = string.Format(@"https://sistrategiacfdi1.blob.core.windows.net/{0}/{1}.xml",
                                                                                    comprobante.Emisor.PublicKey.ToString("N"),
                                                                                    comprobante.PublicKey.ToString("N"));
                                comprobante.Status = "A";
                            }
                        }
                        //using (var fileToCompressStream = new MemoryStream(fileBytes)) {
                        //    fileToCompressStream.CopyTo(entryStream);
                        //}
                    }
                }
            }
            catch (Exception ex) {
                CloudBlockBlob blob2 = container.GetBlockBlobReference(invoiceFileName + "_exception.txt");
                //zipMs.Position = 0;
                blob2.UploadText(ex.ToString());
                blob2.Properties.ContentType = "text/plain";
                blob2.SetMetadata();
                blob2.SetProperties();

                throw;
            }

            return(true);
        }
        public MemoryStream CreatePDF(Comprobante comprobante)
        {
            try {
                MemoryStream outputStream = new MemoryStream();
                Document document = new Document(PageSize.LETTER, 53.858267717f, 51.023622047f, 45.354330709f, 45.354330709f);
                PdfWriter writer = PdfWriter.GetInstance(document, outputStream);
                document.Open();

                //Fonts

                string fontpath = HttpContext.Current.Server.MapPath(@"~/Content/fonts/Verdana/");
                BaseFont Verdana = BaseFont.CreateFont(fontpath + "verdana.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                BaseFont VerdanaBold = BaseFont.CreateFont(fontpath + "verdanab.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                Font VerdanaBold7Color = new Font(VerdanaBold, 7f, Font.NORMAL, new Color(62, 84, 84));
                Font VerdanaBold9Color = new Font(VerdanaBold, 8f, Font.NORMAL, new Color(62, 84, 84));
                Font Verdana9 = new Font(Verdana, 7f, Font.NORMAL, new Color(0, 0, 0));
                Font VerdanaBold10Color = new Font(VerdanaBold, 8f, Font.NORMAL, new Color(62, 84, 84));
                Font Verdana5 = new Font(Verdana, 5f, Font.NORMAL, new Color(0, 0, 0));

                PdfPTable MainTable = new PdfPTable(1);
                MainTable.TotalWidth = 507.401574803f;
                MainTable.LockedWidth = true;
                MainTable.DefaultCell.Border = 0;

                #region Header

                PdfPTable HeaderTable = new PdfPTable(3);
                HeaderTable.TotalWidth = 507.401574803f;
                HeaderTable.LockedWidth = true;
                float[] widhtsHeader = new float[] { 116.220472441f, 198.42519685f, 192.755905512f };
                HeaderTable.SetWidths(widhtsHeader);
                HeaderTable.DefaultCell.Border = 0;

                //Logo de la empresa en Base64
                Byte[] bytes = this.LoadLogoBase64(comprobante.Emisor.LogoUrl);
                Image logo = iTextSharp.text.Image.GetInstance(bytes);
                logo.ScalePercent(30f);
                PdfPCell HeaderLogo = new PdfPCell(logo);
                HeaderLogo.FixedHeight = 93.543307087f;
                HeaderLogo.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                HeaderLogo.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                HeaderLogo.Border = 0;
                HeaderTable.AddCell(HeaderLogo);

                //Tabla Anidada con Datos de emisor
                PdfPTable DatosEmisor = new PdfPTable(1);
                DatosEmisor.DefaultCell.Border = 0;

                PdfPCell CorporateName = new PdfPCell(new Phrase(comprobante.Emisor.Nombre, VerdanaBold9Color));
                //CorporateName.PaddingTop = 20;
                CorporateName.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                CorporateName.Border = Rectangle.NO_BORDER;
                DatosEmisor.AddCell(CorporateName);

                PdfContentByte LineaDatosEmisor = writer.DirectContent;
                LineaDatosEmisor.MoveTo(175.748031496f, document.Top - 17.007874016f);
                LineaDatosEmisor.LineTo(360, document.Top - 17.007874016f);
                LineaDatosEmisor.SetRGBColorStroke(62, 84, 84);
                LineaDatosEmisor.Stroke();

                PdfPTable TableCompanyData = new PdfPTable(1);

                PdfPCell CompanyRFC = new PdfPCell(new Phrase("R.F.C. " + comprobante.Emisor.RFC, Verdana9));
                CompanyRFC.Border = 0;
                TableCompanyData.AddCell(CompanyRFC);

                PdfPCell CompanyCalle = new PdfPCell(new Phrase(comprobante.Emisor.DomicilioFiscal.Calle + " # " + comprobante.Emisor.DomicilioFiscal.NoExterior, Verdana9));
                CompanyCalle.Border = 0;
                TableCompanyData.AddCell(CompanyCalle);

                PdfPCell CompanyColonia = new PdfPCell(new Phrase(comprobante.Emisor.DomicilioFiscal.Colonia + ", C.P. " + comprobante.Emisor.DomicilioFiscal.CodigoPostal, Verdana9));
                CompanyColonia.Border = 0;
                TableCompanyData.AddCell(CompanyColonia);

                PdfPCell CompanyCiudad = new PdfPCell(new Phrase(comprobante.Emisor.DomicilioFiscal.Municipio + ", " + comprobante.Emisor.DomicilioFiscal.Estado + ". " + comprobante.Emisor.DomicilioFiscal.Pais , Verdana9));
                CompanyCiudad.Border = 0;
                TableCompanyData.AddCell(CompanyCiudad);

                PdfPCell CompanyTelefono = new PdfPCell(new Phrase("TEL. " + comprobante.Emisor.Telefono, Verdana9));
                CompanyTelefono.Border = 0;
                TableCompanyData.AddCell(CompanyTelefono);

                PdfPCell CompanyCorreo = new PdfPCell(new Phrase(comprobante.Emisor.Correo, Verdana9));
                CompanyCorreo.Border = 0;
                TableCompanyData.AddCell(CompanyCorreo);

                PdfPCell CompanyRegimen = null;
                if (comprobante.Emisor.RegimenFiscal.Count > 0)
                    CompanyRegimen = new PdfPCell(new Phrase("Régimen Fiscal: " + comprobante.Emisor.RegimenFiscal[0].Regimen, Verdana9));
                else
                    CompanyRegimen = new PdfPCell(new Phrase("Régimen Fiscal: ", Verdana9));

                CompanyRegimen.Border = 0;
                TableCompanyData.AddCell(CompanyRegimen);

                PdfPCell CompanyData = new PdfPCell(TableCompanyData);
                CompanyData.HorizontalAlignment = Rectangle.ALIGN_LEFT;
                CompanyData.PaddingLeft = 20;
                CompanyData.Border = 0;
                DatosEmisor.AddCell(CompanyData);

                HeaderTable.AddCell(DatosEmisor);

                //Tabla Anidada con datos de control de la factura
                PdfPTable ControlDataInvoice = new PdfPTable(2);
                float[] WidthsControlDataInvoice = new float[] { 76.535433071f, 116.220472441f };
                ControlDataInvoice.SetWidths(WidthsControlDataInvoice);

                PdfPCell TextFactura = new PdfPCell(new Phrase("Factura: " + comprobante.Serie + comprobante.Folio, VerdanaBold10Color));
                TextFactura.Colspan = 2;
                TextFactura.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextFactura.Border = 0;
                ControlDataInvoice.AddCell(TextFactura);

                PdfContentByte LineaDatosFactura = writer.DirectContent;
                LineaDatosFactura.MoveTo(374.842519685f, document.Top - 15.007874016f);
                LineaDatosFactura.LineTo(554.763779528f, document.Top - 15.007874016f);
                LineaDatosFactura.SetRGBColorStroke(62, 84, 84);
                LineaDatosFactura.SetLineWidth(1);
                LineaDatosFactura.Stroke();

                PdfPCell TextEmision = new PdfPCell(new Phrase("Emisión", Verdana9));
                TextEmision.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextEmision.Border = 0;
                ControlDataInvoice.AddCell(TextEmision);

                PdfPCell FechaEmision = new PdfPCell(new Phrase(comprobante.Fecha.ToString("dd/MM/yyyy HH:mm:ss"), Verdana9));
                FechaEmision.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                FechaEmision.Border = 0;
                ControlDataInvoice.AddCell(FechaEmision);

                PdfPCell TextFolio = new PdfPCell(new Phrase("Folio Fiscal", Verdana9));
                TextFolio.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextFolio.Border = 0;
                ControlDataInvoice.AddCell(TextFolio);

                string PhraseUUID = "";

                if (comprobante.Status.Equals("A")) {
                    foreach (var complemento in comprobante.Complementos) {
                        if (complemento is TimbreFiscalDigital) {
                            TimbreFiscalDigital timbre = (TimbreFiscalDigital)complemento;
                            if (!String.IsNullOrEmpty(timbre.UUID)) {
                                PhraseUUID = timbre.UUID.ToString();
                            }
                        }
                    }
                    //if (!String.IsNullOrEmpty(comprobante .Complemento.TimbreFiscalDigital.UUID)) {
                    //    PhraseUUID = comprobante.Complemento.TimbreFiscalDigital.UUID.ToString();
                    //}
                }

                PdfPCell Folio = new PdfPCell(new Phrase(PhraseUUID, Verdana9));
                Folio.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Folio.Border = 0;
                ControlDataInvoice.AddCell(Folio);

                PdfPCell TextNoOrden = new PdfPCell(new Phrase("No. de Orden", Verdana9));
                TextNoOrden.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextNoOrden.Border = 0;
                ControlDataInvoice.AddCell(TextNoOrden);

                PdfPCell NoOrden = new PdfPCell(new Phrase(comprobante.ExtendedIntValue1.ToString(), Verdana9));
                NoOrden.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                NoOrden.Border = 0;
                ControlDataInvoice.AddCell(NoOrden);

                PdfPCell TextCliente = new PdfPCell(new Phrase("Cliente", Verdana9));
                TextCliente.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextCliente.Border = 0;
                ControlDataInvoice.AddCell(TextCliente);

                PdfPCell Cliente = new PdfPCell(new Phrase(comprobante.ExtendedIntValue2.ToString(), Verdana9));
                Cliente.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Cliente.Border = 0;
                ControlDataInvoice.AddCell(Cliente);

                PdfPCell TextTransporte = new PdfPCell(new Phrase("Transporte", Verdana9));
                TextTransporte.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextTransporte.Border = 0;
                ControlDataInvoice.AddCell(TextTransporte);

                PdfPCell Transporte = new PdfPCell(new Phrase("CLIENTE", Verdana9));
                Transporte.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Transporte.Border = 0;
                ControlDataInvoice.AddCell(Transporte);

                PdfPCell TextMetodoPago = new PdfPCell(new Phrase("Método de Pago", Verdana9));
                TextMetodoPago.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextMetodoPago.Border = 0;
                ControlDataInvoice.AddCell(TextMetodoPago);

                if (comprobante.MetodoDePago != null) {

                    string metodoPago = comprobante.TipoMetodoDePago.TipoMetodoDePagoCode + "-" + comprobante.TipoMetodoDePago.TipoMetodoDePagoDescription;
                    PdfPCell MetodoPago = new PdfPCell(new Phrase(metodoPago, Verdana9));
                    MetodoPago.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                    MetodoPago.Border = 0;
                    ControlDataInvoice.AddCell(MetodoPago);

                }

                if (comprobante.MetodoDePago != null && (comprobante.MetodoDePago.ToString().Equals("02") || comprobante.MetodoDePago.ToString().Equals("04") || comprobante.MetodoDePago.ToString().Equals("28"))) {

                    PdfPCell TextNoCuenta = new PdfPCell(new Phrase("Número de Cuenta", Verdana9));
                    TextNoCuenta.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                    TextNoCuenta.Border = 0;
                    ControlDataInvoice.AddCell(TextNoCuenta);

                    PdfPCell Cuenta = new PdfPCell(new Phrase(comprobante.NumCtaPago, Verdana9));
                    Cuenta.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                    Cuenta.Border = 0;
                    ControlDataInvoice.AddCell(Cuenta);
                }

                PdfPCell ContentDatosFactura = new PdfPCell(ControlDataInvoice);
                ContentDatosFactura.BorderColor = new Color(62, 84, 84);
                ContentDatosFactura.BorderWidth = 2;

                PdfPCell EspacioTablas = new PdfPCell();
                EspacioTablas.Colspan = 2;
                EspacioTablas.Border = 0;
                ControlDataInvoice.AddCell(EspacioTablas);

                HeaderTable.AddCell(ContentDatosFactura);

                MainTable.AddCell(HeaderTable);

                PdfPCell EspacioTablas1 = new PdfPCell();
                EspacioTablas1.Colspan = 2;
                EspacioTablas1.Border = 0;
                EspacioTablas1.FixedHeight = 7.086614173f;

                MainTable.AddCell(EspacioTablas1);

                #endregion

                #region DatosFacturacion

                PdfPTable DatosReceptor = new PdfPTable(3);
                DatosReceptor.TotalWidth = 507.401574803f;
                DatosReceptor.LockedWidth = true;
                float[] WidthsDatosReceptor = new float[] { 250.866141732f, 5.669291339f, 250.866141732f };
                DatosReceptor.SetWidths(WidthsDatosReceptor);

                PdfPTable DatosFacturacion = new PdfPTable(2);
                DatosFacturacion.TotalWidth = 250.866141732f;
                float[] WidthsDatosFacturacion = new float[] { 70.866141732f, 180f };
                DatosFacturacion.SetWidths(WidthsDatosFacturacion);

                PdfPCell TextDatosFacturacion = new PdfPCell(new Phrase("Datos de Facturación", VerdanaBold9Color));
                TextDatosFacturacion.Colspan = 2;
                TextDatosFacturacion.Border = Rectangle.BOTTOM_BORDER;
                TextDatosFacturacion.BorderColor = new Color(62, 84, 84);
                TextDatosFacturacion.BorderWidth = 1.3f;
                TextDatosFacturacion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                DatosFacturacion.AddCell(TextDatosFacturacion);

                PdfPCell TextoRFC = new PdfPCell(new Phrase("RFC", Verdana9));
                TextoRFC.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoRFC.Border = 0;
                DatosFacturacion.AddCell(TextoRFC);

                PdfPCell RFC = new PdfPCell(new Phrase(comprobante.Receptor.RFC, Verdana9));
                RFC.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                RFC.Border = 0;
                DatosFacturacion.AddCell(RFC);

                PdfPCell TextoNombre = new PdfPCell(new Phrase("Nombre", Verdana9));
                TextoNombre.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoNombre.Border = 0;
                DatosFacturacion.AddCell(TextoNombre);

                PdfPCell Nombre = new PdfPCell(new Phrase(comprobante.Receptor.Nombre, Verdana9));
                Nombre.Border = 0;
                Nombre.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                DatosFacturacion.AddCell(Nombre);

                PdfPCell TextDireccionFiscal = new PdfPCell(new Phrase("Dirección Fiscal", VerdanaBold9Color));
                TextDireccionFiscal.Colspan = 2;
                TextDireccionFiscal.Border = Rectangle.BOTTOM_BORDER | Rectangle.TOP_BORDER;
                TextDireccionFiscal.BorderColor = new Color(62, 84, 84);
                TextDireccionFiscal.BorderWidth = 1.3f;
                TextDireccionFiscal.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                DatosFacturacion.AddCell(TextDireccionFiscal);

                PdfPCell TextoCalle = new PdfPCell(new Phrase("Calle", Verdana9));
                TextoCalle.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoCalle.Border = 0;
                DatosFacturacion.AddCell(TextoCalle);

                PdfPCell Calle = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Calle + " # " + comprobante.Receptor.Domicilio.NoExterior, Verdana9));
                Calle.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Calle.Border = 0;
                DatosFacturacion.AddCell(Calle);

                PdfPCell TextoColonia = new PdfPCell(new Phrase("Colonia", Verdana9));
                TextoColonia.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoColonia.Border = 0;
                DatosFacturacion.AddCell(TextoColonia);

                PdfPCell Colonia = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Colonia, Verdana9));
                Colonia.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Colonia.Border = 0;
                DatosFacturacion.AddCell(Colonia);

                PdfPCell TextoMunicipio = new PdfPCell(new Phrase("Municipio", Verdana9));
                TextoMunicipio.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoMunicipio.Border = 0;
                DatosFacturacion.AddCell(TextoMunicipio);

                PdfPCell Municipio = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Municipio, Verdana9));
                Municipio.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Municipio.Border = 0;
                DatosFacturacion.AddCell(Municipio);

                PdfPCell TextoEstado = new PdfPCell(new Phrase("Estado", Verdana9));
                TextoEstado.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoEstado.Border = 0;
                DatosFacturacion.AddCell(TextoEstado);

                PdfPCell Estado = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Estado, Verdana9));
                Estado.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Estado.Border = 0;
                DatosFacturacion.AddCell(Estado);

                PdfPCell TextoPais = new PdfPCell(new Phrase("País", Verdana9));
                TextoPais.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoPais.Border = 0;
                DatosFacturacion.AddCell(TextoPais);

                PdfPCell Pais = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Pais, Verdana9));
                Pais.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Pais.Border = 0;
                DatosFacturacion.AddCell(Pais);

                PdfPCell TextoCP = new PdfPCell(new Phrase("Código Postal", Verdana9));
                TextoCP.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoCP.Border = 0;
                DatosFacturacion.AddCell(TextoCP);

                PdfPCell CP = new PdfPCell(new Phrase("C.P. " + comprobante.Receptor.Domicilio.CodigoPostal, Verdana9));
                CP.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                CP.Border = 0;
                DatosFacturacion.AddCell(CP);

                PdfPCell CellDatosFacturacion = new PdfPCell(DatosFacturacion);
                CellDatosFacturacion.BorderColor = new Color(62, 84, 84);
                CellDatosFacturacion.BorderWidth = 2;
                CellDatosFacturacion.PaddingRight = 4;
                CellDatosFacturacion.PaddingLeft = 4;
                CellDatosFacturacion.PaddingBottom = 4;

                DatosReceptor.AddCell(CellDatosFacturacion);

                PdfPCell Espacio = new PdfPCell();
                Espacio.Border = 0;

                DatosReceptor.AddCell(Espacio);

                PdfPTable DatosDestinatario = new PdfPTable(2);
                DatosDestinatario.TotalWidth = 250.866141732f;
                DatosDestinatario.SetWidths(WidthsDatosFacturacion);

                PdfPCell TextDestinatarioHeader = new PdfPCell(new Phrase("Destinatario", VerdanaBold9Color));
                TextDestinatarioHeader.Colspan = 2;
                TextDestinatarioHeader.Border = Rectangle.BOTTOM_BORDER;
                TextDestinatarioHeader.BorderColor = new Color(62, 84, 84);
                TextDestinatarioHeader.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextDestinatarioHeader.BorderWidth = 1.3f;
                DatosDestinatario.AddCell(TextDestinatarioHeader);

                PdfPCell TextoDestinatario = new PdfPCell(new Phrase("Destinatario", Verdana9));
                TextoDestinatario.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoDestinatario.Border = 0;
                DatosDestinatario.AddCell(TextoDestinatario);

                PdfPCell Destinatario = new PdfPCell(new Phrase(comprobante.Receptor.Nombre, Verdana9));
                Destinatario.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Destinatario.Border = 0;
                DatosDestinatario.AddCell(Destinatario);

                PdfPCell TextDireccion = new PdfPCell(new Phrase("Dirección", VerdanaBold9Color));
                TextDireccion.Colspan = 2;
                TextDireccion.Border = Rectangle.BOTTOM_BORDER | Rectangle.TOP_BORDER;
                TextDireccion.BorderColor = new Color(62, 84, 84);
                TextDireccion.BorderWidth = 1.3f;
                TextDireccion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                DatosDestinatario.AddCell(TextDireccion);

                DatosDestinatario.AddCell(TextoCalle);

                PdfPCell CalleDireccion = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Calle + " # " + comprobante.Receptor.Domicilio.NoExterior, Verdana9));
                CalleDireccion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                CalleDireccion.Border = 0;
                DatosDestinatario.AddCell(CalleDireccion);

                DatosDestinatario.AddCell(TextoColonia);

                PdfPCell ColoniaDireccion = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Colonia, Verdana9));
                ColoniaDireccion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                ColoniaDireccion.Border = 0;
                DatosDestinatario.AddCell(ColoniaDireccion);

                DatosDestinatario.AddCell(TextoMunicipio);

                PdfPCell MunicipioDireccion = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Municipio, Verdana9));
                MunicipioDireccion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                MunicipioDireccion.Border = 0;
                DatosDestinatario.AddCell(MunicipioDireccion);

                DatosDestinatario.AddCell(TextoEstado);

                PdfPCell EstadoDireccion = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Estado, Verdana9));
                EstadoDireccion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                EstadoDireccion.Border = 0;
                DatosDestinatario.AddCell(EstadoDireccion);

                DatosDestinatario.AddCell(TextoPais);

                PdfPCell PaisDireccion = new PdfPCell(new Phrase(comprobante.Receptor.Domicilio.Pais, Verdana9));
                PaisDireccion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                PaisDireccion.Border = 0;
                DatosDestinatario.AddCell(PaisDireccion);

                DatosDestinatario.AddCell(TextoCP);

                PdfPCell CPDireccion = new PdfPCell(new Phrase("C.P. " + comprobante.Receptor.Domicilio.CodigoPostal, Verdana9));
                CPDireccion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                CPDireccion.Border = 0;
                DatosDestinatario.AddCell(CPDireccion);

                PdfPCell CellDatosDestinatario = new PdfPCell(DatosDestinatario);
                CellDatosDestinatario.BorderColor = new Color(62, 84, 84);
                CellDatosDestinatario.BorderWidth = 2;
                CellDatosDestinatario.PaddingRight = 4;
                CellDatosDestinatario.PaddingLeft = 4;
                CellDatosDestinatario.PaddingBottom = 4;

                DatosReceptor.AddCell(CellDatosDestinatario);

                MainTable.AddCell(DatosReceptor);
                #endregion

                PdfPCell TableDivision = new PdfPCell();
                TableDivision.FixedHeight = 7.086614173f;
                TableDivision.Border = 0;
                MainTable.AddCell(TableDivision);

                #region Conceptos
                PdfPTable Conceptos = new PdfPTable(1);
                Conceptos.TotalWidth = 507.401574803f;
                Conceptos.LockedWidth = true;

                PdfPTable TableConceptos = new PdfPTable(9);
                float[] WidhtsTableConceptos = new float[] { 51.023622047f, 2.834645669f, 63.779527559f, 2.834645669f, 246.614173228f, 2.834645669f, 62.362204724f, 2.834645669f, 65.196850394f };
                TableConceptos.SetWidths(WidhtsTableConceptos);
                TableConceptos.SplitRows = true;//.SpacingAfter = 50f;

                PdfPCell TextoCantidad = new PdfPCell(new Phrase("Cantidad", VerdanaBold9Color));
                TextoCantidad.Border = Rectangle.BOTTOM_BORDER;
                TextoCantidad.BorderWidth = 1.3f;
                TextoCantidad.BorderColor = new Color(62, 84, 84);
                TextoCantidad.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoCantidad.PaddingBottom = 4;
                TableConceptos.AddCell(TextoCantidad);

                PdfPCell Espacio1 = new PdfPCell();
                Espacio1.Border = 0;
                TableConceptos.AddCell(Espacio1);

                PdfPCell TextoClave = new PdfPCell(new Phrase("Clave", VerdanaBold9Color));
                TextoClave.Border = Rectangle.BOTTOM_BORDER;
                TextoClave.BorderWidth = 1.3f;
                TextoClave.BorderColor = new Color(62, 84, 84);
                TextoClave.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoClave.PaddingBottom = 4;
                TableConceptos.AddCell(TextoClave);

                TableConceptos.AddCell(Espacio1);

                PdfPCell TextoDescripción = new PdfPCell(new Phrase("Descripción", VerdanaBold9Color));
                TextoDescripción.Border = Rectangle.BOTTOM_BORDER;
                TextoDescripción.BorderWidth = 1.3f;
                TextoDescripción.BorderColor = new Color(62, 84, 84);
                TextoDescripción.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoDescripción.PaddingBottom = 4;
                TableConceptos.AddCell(TextoDescripción);

                TableConceptos.AddCell(Espacio1);

                PdfPCell TextoPUnitario = new PdfPCell(new Phrase("P. Unitario", VerdanaBold9Color));
                TextoPUnitario.Border = Rectangle.BOTTOM_BORDER;
                TextoPUnitario.BorderWidth = 1.3f;
                TextoPUnitario.BorderColor = new Color(62, 84, 84);
                TextoPUnitario.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoPUnitario.PaddingBottom = 4;
                TableConceptos.AddCell(TextoPUnitario);

                TableConceptos.AddCell(Espacio1);

                PdfPCell TextoImporte = new PdfPCell(new Phrase("Importe", VerdanaBold9Color));
                TextoImporte.Border = Rectangle.BOTTOM_BORDER;
                TextoImporte.BorderWidth = 1.3f;
                TextoImporte.BorderColor = new Color(62, 84, 84);
                TextoImporte.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoImporte.PaddingBottom = 4;
                TableConceptos.AddCell(TextoImporte);

                foreach (Concepto concepto in comprobante.Conceptos) {
                    PdfPCell conceptoCantidad = new PdfPCell(new Phrase(concepto.Cantidad.ToString("0.00"), Verdana9));
                    conceptoCantidad.HorizontalAlignment = Element.ALIGN_CENTER;
                    conceptoCantidad.Border = 0;
                    TableConceptos.AddCell(conceptoCantidad);

                    TableConceptos.AddCell(Espacio1);

                    PdfPCell conceptoClave = new PdfPCell(new Phrase(concepto.NoIdentificacion, Verdana9));
                    conceptoClave.HorizontalAlignment = Element.ALIGN_CENTER;
                    conceptoClave.Border = 0;
                    TableConceptos.AddCell(conceptoClave);

                    TableConceptos.AddCell(Espacio1);

                    PdfPCell conceptoDescripcion = new PdfPCell(new Phrase(concepto.Descripcion, Verdana9));
                    conceptoDescripcion.HorizontalAlignment = Element.ALIGN_CENTER;
                    conceptoDescripcion.Border = 0;
                    TableConceptos.AddCell(conceptoDescripcion);

                    TableConceptos.AddCell(Espacio1);

                    PdfPCell conceptoPUnitario = new PdfPCell(new Phrase("$" + concepto.ValorUnitario.ToString("#,##0.00"), Verdana9));
                    conceptoPUnitario.HorizontalAlignment = Element.ALIGN_CENTER;
                    conceptoPUnitario.Border = 0;
                    TableConceptos.AddCell(conceptoPUnitario);

                    TableConceptos.AddCell(Espacio1);

                    PdfPCell conceptoImporte = new PdfPCell(new Phrase("$" + concepto.Importe.ToString("#,##0.00"), Verdana9));
                    conceptoImporte.HorizontalAlignment = Element.ALIGN_CENTER;
                    conceptoImporte.Border = 0;
                    TableConceptos.AddCell(conceptoImporte);
                }

                PdfPCell CellConceptos = new PdfPCell(TableConceptos);
                CellConceptos.BorderWidth = 2;
                CellConceptos.BorderColor = new Color(62, 84, 84);
                CellConceptos.PaddingRight = 4;
                CellConceptos.PaddingLeft = 4;
                CellConceptos.MinimumHeight = 184.251968504f;

                Conceptos.AddCell(CellConceptos);

                MainTable.AddCell(Conceptos);

                #endregion

                MainTable.AddCell(TableDivision);

                PdfPTable FooterContent = new PdfPTable(1);
                FooterContent.TotalWidth = 507.401574803f;
                FooterContent.LockedWidth = true;

                FooterContent.DefaultCell.Border = 0;

                PdfPTable Footer = new PdfPTable(2);
                Footer.DefaultCell.Border = 0;
                float[] WidthsFooter = new float[] { 86.456692913f, 420.94488189f };
                Footer.TotalWidth = 507.401574803f;
                Footer.LockedWidth = true;
                Footer.SetWidths(WidthsFooter);

                 //CIF empresa en Base64
                Byte[] bytes2 = LoadCIFBase64(comprobante.Emisor.CifUrl);

                Image CIFImage = iTextSharp.text.Image.GetInstance(bytes2);
                CIFImage.ScaleAbsoluteWidth(76.535433071f);
                CIFImage.ScaleAbsoluteHeight(155.905511811f);

                PdfPCell CIF = new PdfPCell(CIFImage);
                CIF.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                CIF.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                CIF.Border = Rectangle.RIGHT_BORDER;
                CIF.BorderColor = new Color(62, 84, 84);
                CIF.BorderWidth = 1.3f;

                Footer.AddCell(CIF);

                PdfPTable FooterRight = new PdfPTable(1);
                FooterRight.DefaultCell.Border = 0;

                PdfPTable TableFooterTop = new PdfPTable(2);
                TableFooterTop.DefaultCell.Border = 0;
                float[] WidhtsFooterTop = new float[] { 198.42519685f, 222.519685039f };
                TableFooterTop.SetWidths(WidhtsFooterTop);

                PdfPTable FooterTopLeft = new PdfPTable(1);
                FooterTopLeft.DefaultCell.Border = 0;

                Font CamposSAT = new Font();
                CamposSAT = FontFactory.GetFont("Arial", 8.0f, Font.NORMAL, new Color(0, 0, 0));

                PdfPTable TableCertificacion = new PdfPTable(1);

                string PhraseFechaCertificacion = "";
                if (comprobante.Status.Equals("A")) {
                    foreach (var complemento in comprobante.Complementos) {
                        if (complemento is TimbreFiscalDigital) {
                            TimbreFiscalDigital timbre = (TimbreFiscalDigital)complemento;
                            //if (!String.IsNullOrEmpty(timbre.FechaTimbrado)) {
                            PhraseUUID = timbre.FechaTimbrado.ToString("dd/MM/yyyy HH:mm:ss");
                            //}
                        }
                    }
                    //if (!String.IsNullOrEmpty(comprobante.Complemento.TimbreFiscalDigital.FechaTimbrado.ToString())) {
                    //    PhraseFechaCertificacion = comprobante.Complemento.TimbreFiscalDigital.FechaTimbrado.ToString("dd/MM/yyyy HH:mm:ss");
                    //}
                }

                PdfPCell Certificacion = new PdfPCell(new Phrase("Certificación: " + PhraseFechaCertificacion + "\n", VerdanaBold9Color));
                Certificacion.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Certificacion.VerticalAlignment = Rectangle.ALIGN_CENTER;
                Certificacion.Border = 0;
                TableCertificacion.AddCell(Certificacion);

                TableCertificacion.AddCell(Espacio1);

                PdfPCell CadenaSAT = new PdfPCell(new Phrase("Cadena SAT", VerdanaBold9Color));
                CadenaSAT.FixedHeight = 14.173228346f;
                CadenaSAT.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                CadenaSAT.VerticalAlignment = Rectangle.ALIGN_CENTER;
                CadenaSAT.Border = Rectangle.TOP_BORDER | Rectangle.BOTTOM_BORDER;
                CadenaSAT.BorderColor = new Color(62, 84, 84);
                CadenaSAT.BorderWidth = 1.3f;
                TableCertificacion.AddCell(CadenaSAT);

                string cadenaSAT = comprobante.GetCadenaOriginal(); // .CadenaOriginal;
                //if (comprobante.Version.Equals("3.2"))
                    cadenaSAT = comprobante.GetCadenaSAT(); // .CadenaSAT;

                PdfPCell Cadena = new PdfPCell(new Phrase(cadenaSAT, Verdana5));
                Cadena.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Cadena.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                Cadena.Border = 0;
                TableCertificacion.AddCell(Cadena);

                PdfPCell CellCertificacion = new PdfPCell(TableCertificacion);
                CellCertificacion.Padding = 3;
                CellCertificacion.Border = Rectangle.BOTTOM_BORDER;
                CellCertificacion.BorderColor = new Color(62, 84, 84);
                CellCertificacion.BorderWidth = 1.3f;

                FooterTopLeft.AddCell(CellCertificacion);

                PdfPCell CellFooterTopLeft = new PdfPCell(FooterTopLeft);
                CellFooterTopLeft.Border = 0;
                CellFooterTopLeft.MinimumHeight = 68.031496063f;
                TableFooterTop.AddCell(CellFooterTopLeft);

                PdfPTable FooterTopRight = new PdfPTable(2);
                FooterTopRight.DefaultCell.Border = 0;
                float[] WidthsFooterTopRight = new float[] { 53.858267717f, 167.244094488f };
                FooterTopRight.SetWidths(WidthsFooterTopRight);

                PdfPCell TextoSubtotal = new PdfPCell(new Phrase("Subtotal", Verdana9));
                TextoSubtotal.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoSubtotal.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                TextoSubtotal.Border = 0;
                FooterTopRight.AddCell(TextoSubtotal);

                PdfPCell Subtotal = new PdfPCell(new Phrase("$" + comprobante.SubTotal.ToString("#,##0.00"), Verdana9));
                Subtotal.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Subtotal.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                Subtotal.Border = 0;
                FooterTopRight.AddCell(Subtotal);

                PdfPCell TextoIVA = new PdfPCell(new Phrase("16 % IVA", Verdana9));
                TextoIVA.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoIVA.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                TextoIVA.Border = 0;
                FooterTopRight.AddCell(TextoIVA);

                PdfPCell IVA = new PdfPCell(new Phrase("$" + comprobante.Impuestos.TotalImpuestosTrasladados.Value.ToString("#,##0.00"), Verdana9));
                IVA.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                IVA.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                IVA.Border = 0;
                FooterTopRight.AddCell(IVA);

                PdfPCell TextoTotal = new PdfPCell(new Phrase("Total", Verdana9));
                TextoTotal.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                TextoTotal.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                TextoTotal.Border = 0;
                FooterTopRight.AddCell(TextoTotal);

                PdfPCell Total = new PdfPCell(new Phrase("$" + comprobante.Total.ToString("#,##0.00"), Verdana9));
                Total.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Total.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                Total.Border = 0;
                FooterTopRight.AddCell(Total);

                PdfPTable TableTotalLetra = new PdfPTable(2);

                CantidadEnLetraConverter letraConverter = new CantidadEnLetraConverter();
                letraConverter.Numero = comprobante.Total;
                //this.TotalLetra = letraConverter.letra();

                //PdfPCell CellTableLetra = new PdfPCell(new Phrase(SATManager.GetImporteConLetra(comprobante.Total) + "  M.N", VerdanaBold7Color));
                PdfPCell CellTableLetra = new PdfPCell(new Phrase(letraConverter.letra() + "  M.N", VerdanaBold7Color));
                CellTableLetra.Colspan = 2;
                CellTableLetra.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                CellTableLetra.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                CellTableLetra.Border = Rectangle.TOP_BORDER;
                CellTableLetra.BorderColor = new Color(62, 84, 84);
                CellTableLetra.BorderWidth = 1.3f;
                TableTotalLetra.AddCell(CellTableLetra);

                PdfPCell TotalLetra = new PdfPCell(TableTotalLetra);
                TotalLetra.Border = Rectangle.BOTTOM_BORDER;
                TotalLetra.BorderColor = new Color(62, 84, 84);
                TotalLetra.BorderWidth = 1.3f;
                TotalLetra.Colspan = 2;
                TotalLetra.PaddingTop = 3;
                TotalLetra.PaddingLeft = 3;

                FooterTopRight.AddCell(TotalLetra);

                PdfPCell CellFooterTopRight = new PdfPCell(FooterTopRight);
                CellFooterTopRight.MinimumHeight = 68.031496063f;
                CellFooterTopRight.Border = Rectangle.LEFT_BORDER;
                CellFooterTopRight.BorderColor = new Color(62, 84, 84);
                CellFooterTopRight.BorderWidth = 1.3f;
                TableFooterTop.AddCell(CellFooterTopRight);

                FooterRight.AddCell(TableFooterTop);

                PdfPTable TableFooterBottom = new PdfPTable(2);
                float[] WidhtsFooterBottom = new float[] { 92.125984252f, 328.818897638f };
                TableFooterBottom.SetWidths(WidhtsFooterBottom);

                PdfPTable FooterBottomLeft = new PdfPTable(1);

                ///QRCODE
                ///
                if (!String.IsNullOrEmpty(comprobante.GetQrCode())) {
                    Byte[] QRCODEBase64 = Convert.FromBase64String(comprobante.GetQrCode());
                    Image QRCODEImage = iTextSharp.text.Image.GetInstance(QRCODEBase64);
                    QRCODEImage.ScaleAbsoluteWidth(76.535433071f);
                    QRCODEImage.ScaleAbsoluteHeight(76.535433071f);

                    PdfPCell CellFooterBottomLeft = new PdfPCell(QRCODEImage, false);
                    CellFooterBottomLeft.MinimumHeight = 85.039370079f;
                    CellFooterBottomLeft.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                    CellFooterBottomLeft.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                    CellFooterBottomLeft.Border = Rectangle.RIGHT_BORDER;
                    CellFooterBottomLeft.BorderColor = new Color(62, 84, 84);
                    CellFooterBottomLeft.BorderWidth = 1.3f;
                    TableFooterBottom.AddCell(CellFooterBottomLeft);
                }
                else {
                    TableFooterBottom.AddCell("");
                }

                PdfPTable TableRightFooter = new PdfPTable(1);

                string PhraseCertificadoSAT = "";

                if (comprobante.Status.Equals("A"))
                {
                    foreach (var complemento in comprobante.Complementos) {
                        if (complemento is TimbreFiscalDigital) {
                            TimbreFiscalDigital timbre = (TimbreFiscalDigital)complemento;
                            if (!String.IsNullOrEmpty(timbre.NoCertificadoSAT)) {
                                PhraseCertificadoSAT = timbre.NoCertificadoSAT.ToString();
                            }
                        }
                    }

                    //if (!String.IsNullOrEmpty(comprobante.Complemento.TimbreFiscalDigital.NoCertificadoSAT))
                    //{
                    //    PhraseCertificadoSAT = comprobante.Complemento.TimbreFiscalDigital.NoCertificadoSAT.ToString();
                    //}
                }

                PdfPCell Certificado = new PdfPCell(new Phrase("Certificado SAT: " + PhraseCertificadoSAT, VerdanaBold9Color));
                Certificado.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Certificado.VerticalAlignment = Rectangle.ALIGN_CENTER;
                Certificado.Border = 0;
                Certificado.PaddingTop = 0;
                TableRightFooter.AddCell(Certificado);

                TableRightFooter.AddCell(Espacio1);

                PdfPCell Sellos = new PdfPCell(new Phrase("Sellos Digitales", VerdanaBold9Color));
                Sellos.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Sellos.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                Sellos.Padding = 3;
                Sellos.Border = Rectangle.TOP_BORDER | Rectangle.BOTTOM_BORDER;
                Sellos.BorderColor = new Color(62, 84, 84);
                Sellos.BorderWidth = 1.3f;
                TableRightFooter.AddCell(Sellos);

                PdfPCell SelloCFD = new PdfPCell(new Phrase("Sello CFDI: " + comprobante.Sello, Verdana5));
                SelloCFD.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                SelloCFD.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                SelloCFD.Padding = 3;
                SelloCFD.Border = 0;
                TableRightFooter.AddCell(SelloCFD);

                string PhraseSelloSat = "";

                if (comprobante.Status.Equals("A")) {
                    foreach (var complemento in comprobante.Complementos) {
                        if (complemento is TimbreFiscalDigital) {
                            TimbreFiscalDigital timbre = (TimbreFiscalDigital)complemento;
                            if (!String.IsNullOrEmpty(timbre.SelloSAT)) {
                                PhraseSelloSat = timbre.SelloSAT.ToString();
                            }
                        }
                    }
                }

                PdfPCell SelloSAT = new PdfPCell(new Phrase("Sello SAT: " + PhraseSelloSat, Verdana5));
                SelloSAT.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                SelloSAT.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                SelloSAT.Padding = 3;
                SelloSAT.Border = Rectangle.BOTTOM_BORDER;
                SelloSAT.BorderColor = new Color(62, 84, 84);
                SelloSAT.BorderWidth = 1.3f;
                TableRightFooter.AddCell(SelloSAT);

                TableRightFooter.AddCell(Espacio1);

                PdfPCell Leyenda = new PdfPCell(new Phrase("Este documento es una representación impresa de un CFDI.", VerdanaBold9Color));
                Leyenda.HorizontalAlignment = Rectangle.ALIGN_CENTER;
                Leyenda.VerticalAlignment = Rectangle.ALIGN_MIDDLE;
                Leyenda.Padding = 0;
                Leyenda.Border = 0;
                TableRightFooter.AddCell(Leyenda);

                PdfPCell CellFooterBottomRight = new PdfPCell(TableRightFooter);
                CellFooterBottomRight.Padding = 4;
                CellFooterBottomRight.Border = 0;
                CellFooterTopRight.MinimumHeight = 68.031496063f;
                TableFooterBottom.AddCell(CellFooterBottomRight);

                FooterRight.AddCell(TableFooterBottom);

                Footer.AddCell(FooterRight);

                PdfPCell CellFooter = new PdfPCell(Footer);
                CellFooter.BorderColor = new Color(62, 84, 84);
                CellFooter.BorderWidth = 2;

                MainTable.AddCell(CellFooter);

                document.Add(MainTable);

                if (comprobante.Status.ToString().Equals("C")) {
                    string urlImage = HttpContext.Current.Server.MapPath("~/Content/Invoice/cancelado.png");
                    Image watermark2 = Image.GetInstance(urlImage);
                    watermark2.SetAbsolutePosition(120, 300);

                    document.Add(watermark2);
                }

                writer.CloseStream = false;
                document.Close();
                outputStream.Flush();
                outputStream.Position = 0;

                return outputStream;

                //throw new NotImplementedException();
            }
            catch (Exception ex) {

                ex.Message.ToString();
                return null;
            }
        }
        public JsonResult Create(ComprobanteCreateViewModel model)
        {
            try {
                if (String.IsNullOrEmpty(model.LugarExpedicion))
                    throw new ApplicationException("¡Ingrese el lugar de expedición!");
                else if (string.IsNullOrEmpty(model.TipoDeComprobante))
                    throw new ApplicationException("¡Ingrese el tipo de comprobante!");
                else if (model.EmisorId <= 0)
                    throw new ApplicationException("¡Ingrese el emisor!");
                else if (model.ReceptorId <= 0)
                    throw new ApplicationException("¡Ingrese el receptor!");
                else if (model.CertificadoId <= 0)
                    throw new ApplicationException("¡Ingrese el certificado!");
                else if (String.IsNullOrEmpty(model.FormaDePago))
                    throw new ApplicationException("¡Ingrese la forma de pago!");
                else if (String.IsNullOrEmpty(model.MetodoDePago))
                    throw new ApplicationException("¡Ingrese el método de pago!");
                else if ((model.MetodoDePago != "EFECTIVO" && model.MetodoDePago != "NO IDENTIFICADO") && (model.NumCtaPago == null || (model.NumCtaPago.Count() > 6 || model.NumCtaPago.Count() < 4)))
                    throw new ApplicationException("¡El valor de NumCtaPago debe contener entre 4 hasta 6 caracteres!");
                else if ((model.MetodoDePago != "EFECTIVO" && model.MetodoDePago != "NO IDENTIFICADO") && (string.IsNullOrEmpty(model.Banco)))
                    throw new ApplicationException("¡Ingrese el banco!");
                else if ((model.Conceptos != null || model.Conceptos.Count > 0)
                    && model.Conceptos.All(x => x.Cantidad < 0m || x.Unidad == null || x.Descripcion == null || x.ValorUnitario < 0m))
                    throw new ApplicationException("¡Ingrese al menos un concepto!");
                else if (model.SubTotal < 0m)
                    throw new ApplicationException("¡SubTotal no válido!");
                else if (model.TotalImpuestosTrasladados < 0m)
                    throw new ApplicationException("¡Total Impuestos Trasladados no válido!");
                else if (model.TotalImpuestosRetenidos < 0m)
                    throw new ApplicationException("¡Total Impuestos Retenidos no válido!");
                else if (model.Total < 0m)
                    throw new ApplicationException("¡Total no válido!");
                else {

                    var comprobante = new Comprobante();

                    Emisor emisor = DBContext.Emisores.Find(model.EmisorId);

                    ComprobanteEmisor comprobanteEmisor = null;

                    if (model.ExpedidoEn != null && model.ExpedidoEn.UbicacionId != null) {
                        comprobanteEmisor = DBContext.ComprobantesEmisores.Where(e => e.EmisorId == emisor.EmisorId && e.DomicilioFiscalId == emisor.DomicilioFiscalId && e.ExpedidoEnId == model.ExpedidoEn.UbicacionId).SingleOrDefault();
                    }
                    //else if () {
                    //}
                    else {
                        // crear o seleccionar la ubicación y agregarla
                        //comprobanteEmisor = DBContext.ComprobantesEmisores.Where(e => e.EmisorId == model.EmisorId && e.DomicilioFiscalId == model.DomicilioFiscalId && e.ExpedidoEnId == model.ExpedidoEnId);
                        comprobanteEmisor = DBContext.ComprobantesEmisores.Where(e => e.EmisorId == emisor.EmisorId && e.DomicilioFiscalId == emisor.DomicilioFiscalId && e.ExpedidoEnId == model.ExpedidoEn.UbicacionId).SingleOrDefault();
                    }

                    // Crear uno nuevo
                    if (comprobanteEmisor == null) {
                        comprobanteEmisor = new ComprobanteEmisor {
                            Emisor = emisor,
                            //EmisorId = emisor.EmisorId,
                            DomicilioFiscal = emisor.DomicilioFiscal
                            //,DomicilioId = receptor.DomicilioId
                            // TODO:
                            //RegimenFiscal = emisor.RegimenFiscal
                        };

                    }

                    comprobante.Emisor = comprobanteEmisor;

                    //comprobante.EmisorId = model.EmisorId;
                    //comprobante.Emisor = DBContext.Emisores.Find(model.EmisorId); // .Where(e => e.PublicKey == publicKey).SingleOrDefault();
                    //if (model.Emisor. .ExpedidoEnId != null) {
                    //    comprobante.Emisor = DBContext.ComprobantesEmisores.Where(e => e.EmisorId == model.EmisorId && e.DomicilioFiscalId == model.DomicilioFiscalId && e.ExpedidoEnId == model.ExpedidoEnId);
                    //}
                    //else {
                    //    comprobante.Emisor = DBContext.ComprobantesEmisores.Where(e => e.EmisorId == model.EmisorId && e.DomicilioFiscalId == model.DomicilioFiscalId && e.ExpedidoEnId == model.ExpedidoEnId);
                    //}

                    Receptor receptor = DBContext.Receptores.Find(model.ReceptorId);

                    ComprobanteReceptor comprobanteReceptor = DBContext.ComprobantesReceptores.Where(r => r.ReceptorId == receptor.ReceptorId && r.DomicilioId == receptor.DomicilioId).SingleOrDefault();

                    // Crear uno nuevo
                    if (comprobanteReceptor == null) {
                        comprobanteReceptor = new ComprobanteReceptor {
                            Receptor = receptor,
                            //ReceptorId = receptor.ReceptorId,
                            Domicilio = receptor.Domicilio
                            //,DomicilioId = receptor.DomicilioId
                        };
                    }

                    //comprobante.ReceptorId = model.ReceptorId;
                    //comprobante.Receptor = DBContext.Receptores.Find(model.ReceptorId); // .Where(e => e.PublicKey == publicKey).SingleOrDefault();
                    comprobante.Receptor = comprobanteReceptor;
                    comprobante.Serie = model.Serie;
                    comprobante.Folio = model.Folio;
                    comprobante.Fecha = DateTime.Now + SATManager.GetCFDIServiceTimeSpan();
                    comprobante.FormaDePago = model.FormaDePago;
                    comprobante.SubTotal = model.SubTotal;
                    comprobante.Total = model.Total;

                    //comprobante.NoCertificado;
                    //comprobante.Certificado;
                    comprobante.TipoDeComprobante = model.TipoDeComprobante;

                    comprobante.ExtendedIntValue1 = model.OrdenNumero;
                    comprobante.ExtendedIntValue2 = model.CteNumero;
                    comprobante.ExtendedStringValue2 = model.Notas;

                    comprobante.ViewTemplateId = model.TemplateId;

                    comprobante.FormaDePago = model.FormaDePago;
                    comprobante.MetodoDePago = model.MetodoDePago;
                    comprobante.LugarExpedicion = model.LugarExpedicion;
                    comprobante.TipoCambio = model.TipoCambio;
                    comprobante.Moneda = model.Moneda;
                    comprobante.NumCtaPago = model.NumCtaPago;
                    comprobante.ExtendedStringValue1 = model.Banco;
                    comprobante.Moneda = model.Moneda;

                    comprobante.Conceptos = new List<Concepto>();

                    foreach (var modelConcepto in model.Conceptos) {
                        if (!string.IsNullOrEmpty(modelConcepto.Descripcion)) {
                            comprobante.Conceptos.Add(new Concepto {
                                Cantidad = modelConcepto.Cantidad,
                                Unidad = modelConcepto.Unidad,
                                NoIdentificacion = modelConcepto.NoIdentificacion,
                                Descripcion = modelConcepto.Descripcion,
                                ValorUnitario = modelConcepto.ValorUnitario,
                                Importe = modelConcepto.Importe,
                                PublicKey = Guid.NewGuid(),
                                Ordinal = modelConcepto.Ordinal
                            });
                        }
                    }

                    comprobante.Impuestos = new Impuestos();
                    comprobante.Impuestos.Traslados = new List<Traslado>();

                    foreach (var modelTraslado in model.Traslados) {
                        if (modelTraslado.Tasa > 0 && modelTraslado.Importe > 0) {
                            comprobante.Impuestos.Traslados.Add(new Traslado {
                                Importe = modelTraslado.Importe,
                                Impuesto = modelTraslado.Impuesto,
                                Tasa = modelTraslado.Tasa,
                            });
                        }
                    }

                    comprobante.Impuestos.Retenciones = new List<Retencion>();
                    foreach (var modelRetencion in model.Retenciones) {
                        if (modelRetencion.Importe > 0) {
                            comprobante.Impuestos.Retenciones.Add(new Retencion {
                                Importe = modelRetencion.Importe,
                                Impuesto = modelRetencion.Impuesto,
                            });
                        }
                    }

                    if (model.TotalImpuestosRetenidos > 0)
                        comprobante.Impuestos.TotalImpuestosRetenidos = model.TotalImpuestosRetenidos;

                    if (model.TotalImpuestosTrasladados > 0)
                        comprobante.Impuestos.TotalImpuestosTrasladados = model.TotalImpuestosTrasladados;

                    comprobante.PublicKey = Guid.NewGuid();

                    Certificado certificado = DBContext.Certificados.Find(model.CertificadoId);

                    if (certificado != null) {
                        // comprobante.NoCertificado = certificado.NumSerie;
                        // comprobante.Certificado = certificado.CertificadoBase64;
                        comprobante.CertificadoId = certificado.CertificadoId;
                        comprobante.Certificado = certificado;
                        comprobante.HasNoCertificado = true;
                        comprobante.HasCertificado = true;
                    }

                    string cadenaOriginal = comprobante.GetCadenaOriginal();
                    comprobante.Sello = certificado.GetSello(cadenaOriginal);
                    //comprobante.Status = "P";
                    DBContext.Comprobantes.Add(comprobante);
                    DBContext.SaveChanges();

                    TempData["success"] = "Se ha creado el comprobante correctamente";
                    var data = new {
                        error = false,
                        errorMsg = "",
                        comprobanteId = comprobante.PublicKey
                    };
                    return Json(data);
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dex) {
                string errorTxt = dex.Message.ToString();

                foreach (var valError in dex.EntityValidationErrors)
                {
                    foreach (var error in valError.ValidationErrors)
                    {
                        errorTxt = errorTxt + Environment.NewLine + error.ErrorMessage;
                    }
                }

                var data = new {
                    error = true,
                    errorMsg = errorTxt

                };

                return Json(data);
            }
            catch (Exception ex) {

                string errorTxt = ex.Message.ToString();

                foreach (ModelState modelState in ViewData.ModelState.Values)
                {
                    foreach (ModelError error in modelState.Errors)
                    {
                        errorTxt = errorTxt + Environment.NewLine + error.ErrorMessage;
                    }
                }

                var data = new {
                    error = true,
                    errorMsg = errorTxt

                };

                return Json(data);
            }
        }
        public ComprobanteHtmlViewModel(Comprobante comprobante)
        {
            this.Traslados = new List<ComprobanteImpuestoTrasladoTotalPorTipoViewModel>();

            if (comprobante == null)
                throw new ArgumentNullException("comprobante");

            if (comprobante.Emisor != null) {
                this.Emisor = new ComprobanteEmisorDetailViewModel(comprobante.Emisor);
            }

            if (comprobante.Receptor != null) {
                this.Receptor = new ComprobanteReceptorDetailsViewModel(comprobante.Receptor);
            }

            if (comprobante.Conceptos != null && comprobante.Conceptos.Count > 0) {
                this.Conceptos = new List<ConceptoViewModel>();
                foreach (Concepto concepto in comprobante.Conceptos) {
                    this.Conceptos.Add(new ConceptoViewModel(concepto));
                }
            }

            if (comprobante.Impuestos.Traslados != null && comprobante.Impuestos.Traslados.Count > 0) {
                this.Traslados = comprobante.Impuestos.Traslados
                    .GroupBy(traslado => new { traslado.Impuesto, traslado.Tasa })
                    .OrderByDescending(traslado => traslado.First().Impuesto)
                    .ThenBy(traslado => traslado.First().Tasa)
                    .Select(trasladoGrouped =>
                        new ComprobanteImpuestoTrasladoTotalPorTipoViewModel() {
                            Tasa = String.Format("{0}% {1}", (int)trasladoGrouped.First().Tasa, trasladoGrouped.First().Impuesto),
                            Importe = String.Format("{0:C2}", trasladoGrouped.Sum(t => t.Importe))
                        }
                    ).ToList();
            }

            this.PublicKey = comprobante.PublicKey;
            this.TipoDeComprobante = comprobante.TipoDeComprobante;
            this.Fecha = comprobante.Fecha.ToString("dd/MM/yyyy HH:mm:ss");
            this.Serie = comprobante.Serie;
            this.Folio = comprobante.Folio;

            //this.FolioFiscal = comprobante.

            this.SubTotal = comprobante.SubTotal;
            if (comprobante.Impuestos != null && comprobante.Impuestos.TotalImpuestosTrasladados.HasValue)
                this.IVA = comprobante.Impuestos.TotalImpuestosTrasladados.Value;
            this.Total = comprobante.Total;

            CantidadEnLetraConverter letraConverter = new CantidadEnLetraConverter();
            letraConverter.Numero = comprobante.Total;
            this.TotalLetra = letraConverter.letra();

            this.MetodoDePago = comprobante.MetodoDePago;
            this.NumCuenta = comprobante.NumCtaPago;

            this.MainCss = ConfigurationManager.AppSettings["InvoiceMainCss"];
            this.PrintCss = ConfigurationManager.AppSettings["InvoicePrintCss"];

            this.EmisorLogoUrl = comprobante.Emisor.LogoUrl;
            this.EmisorTelefono = comprobante.Emisor.Telefono;
            this.EmisorCorreo = comprobante.Emisor.Correo;
            this.EmisorCifUrl = comprobante.Emisor.CifUrl;

            this.NoOrden = comprobante.ExtendedIntValue1.ToString();
            this.NoCliente = comprobante.ExtendedIntValue2.ToString();

            this.Notas = comprobante.ExtendedStringValue2;

            //this.FechaTimbre
            //this.CadenaSAT = comprobante.GetCadenaSAT();
            //this.CBB
            //this.NumSerieSAT
            this.SelloCFD = comprobante.Sello;
            //this.SelloSAT = comprobante.Complementos.
            foreach (Complemento complemento in comprobante.Complementos) {
                if (complemento is TimbreFiscalDigital) {
                    TimbreFiscalDigital timbre = complemento as TimbreFiscalDigital;
                    this.SelloSAT = timbre.SelloSAT;
                    this.FechaTimbre = timbre.FechaTimbrado.ToString("dd/MM/yyyy HH:mm:ss");
                    this.FolioFiscal = timbre.UUID;
                    this.NumSerieSAT = timbre.NoCertificadoSAT;
                    this.CadenaSAT = comprobante.GetCadenaSAT();
                    this.CBB = comprobante.GetQrCode();
                }
            }
        }
        public ComprobanteEditViewModel(Comprobante comprobante)
        {
            if (comprobante == null)
                throw new ArgumentNullException("comprobante");

            if (comprobante.Emisor != null) {
                this.Emisor = new EmisorDetailViewModel(comprobante.Emisor.Emisor);
            }

            if (comprobante.Receptor != null) {
                this.Receptor = new ReceptorDetailsViewModel(comprobante.Receptor.Receptor);
            }

            if (comprobante.Conceptos != null && comprobante.Conceptos.Count > 0) {
                this.Conceptos = new List<ConceptoViewModel>();
                foreach (Concepto concepto in comprobante.Conceptos) {
                    this.Conceptos.Add(new ConceptoViewModel(concepto));
                }
            }

            if (comprobante.Impuestos.Traslados != null && comprobante.Impuestos.Traslados.Count > 0) {
                this.Traslados = new List<TrasladoViewModel>();
                foreach (Traslado traslado in comprobante.Impuestos.Traslados) {
                    this.Traslados.Add(new TrasladoViewModel(traslado));
                }
            }

            if (comprobante.Impuestos.Retenciones != null && comprobante.Impuestos.Retenciones.Count > 0) {
                this.Retenciones = new List<RetencionViewModel>();
                foreach (Retencion retencion in comprobante.Impuestos.Retenciones) {
                    this.Retenciones.Add(new RetencionViewModel(retencion));
                }
            }

            this.ComprobanteId = comprobante.ComprobanteId;
            this.EmisorId = comprobante.ComprobanteEmisorId;
            //this.DomicilioFiscalId = comprobante.Emisor.DomicilioFiscalId;
            //this.ExpedidoEnId = comprobante.Emisor.DomicilioFiscalId;
            this.CertificadoId = comprobante.CertificadoId;
            this.ReceptorId = comprobante.ComprobanteReceptorId;

            this.MetodoDePago = comprobante.MetodoDePago;
            this.LugarExpedicion = comprobante.LugarExpedicion;
            this.FormaDePago = comprobante.FormaDePago;

            this.Serie = comprobante.Serie;
            this.Folio = comprobante.Folio;
            this.Fecha = comprobante.Fecha.ToString("yyyy-MM-ddTHH:mm:ss");

            this.TipoCambio = comprobante.TipoCambio;
            this.Moneda = comprobante.Moneda;

            this.Banco = comprobante.ExtendedStringValue1;

            this.SubTotal = comprobante.SubTotal;
            this.Total = comprobante.Total;

            this.TotalImpuestosRetenidos = comprobante.Impuestos.TotalImpuestosRetenidos;
            this.TotalImpuestosTrasladados = comprobante.Impuestos.TotalImpuestosTrasladados;

            this.Notas = comprobante.ExtendedStringValue2;

            this.CadenaOriginal = comprobante.GetCadenaOriginal();
            this.Sello = comprobante.Sello;
            Sistrategia.SAT.CFDiWebSite.Data.ApplicationDbContext DBContext = new Sistrategia.SAT.CFDiWebSite.Data.ApplicationDbContext();
            var certificado = DBContext.Certificados.Where(e => e.NumSerie == comprobante.NoCertificado).SingleOrDefault();
            this.GetSello = certificado.GetSello(this.CadenaOriginal);
        }
        public ComprobanteDetailViewModel(Comprobante comprobante)
        {
            if (comprobante == null)
                throw new ArgumentNullException("comprobante");

            this.PublicKey = comprobante.PublicKey;

            if (comprobante.Emisor != null) {
                this.Emisor = new ComprobanteEmisorDetailViewModel(comprobante.Emisor);
            }

            if (comprobante.Receptor != null) {
                this.Receptor = new ComprobanteReceptorDetailsViewModel(comprobante.Receptor);
            }

            if (comprobante.Conceptos != null && comprobante.Conceptos.Count > 0) {
                this.Conceptos = new List<ConceptoViewModel>();
                foreach (Concepto concepto in comprobante.Conceptos) {
                    this.Conceptos.Add(new ConceptoViewModel(concepto));
                }
            }

            this.Serie = comprobante.Serie;
            this.Folio = comprobante.Folio;

            this.SubTotal = comprobante.SubTotal;
            this.Total = comprobante.Total;

            this.CadenaOriginal = comprobante.GeneratedCadenaOriginal; // comprobante.GetCadenaOriginal();
            //this.Sello = comprobante.Sello;
            this.Sello = comprobante.Sello;
            //this.Sello = comprobante.Sello;

            this.GeneratedXmlUrl = comprobante.GeneratedXmlUrl;
            this.GeneratedPDFUrl = comprobante.GeneratedPDFUrl;

            this.TimbreFiscalDigital = null;

            this.Status = comprobante.Status;

            if (comprobante.Complementos != null && comprobante.Complementos.Count > 0) {
                foreach (var complemento in comprobante.Complementos) {
                    if (complemento is TimbreFiscalDigital) {
                        this.TimbreFiscalDigital = complemento as TimbreFiscalDigital;
                    }
                }
            }
        }
        public ComprobanteHtmlViewModel(Comprobante comprobante) {
            if (comprobante == null)
                throw new ArgumentNullException("comprobante");

            if (comprobante.Emisor != null) {
                this.Emisor = new EmisorDetailViewModel(comprobante.Emisor);
            }

            if (comprobante.Receptor != null) {
                this.Receptor = new ReceptorDetailsViewModel(comprobante.Receptor);
            }

            if (comprobante.Conceptos != null && comprobante.Conceptos.Count > 0) {
                this.Conceptos = new List<ConceptoViewModel>();
                foreach (Concepto concepto in comprobante.Conceptos) {
                    this.Conceptos.Add(new ConceptoViewModel(concepto));
                }
            }

            this.PublicKey = comprobante.PublicKey;

            this.Fecha = comprobante.Fecha.ToString("dd/MM/yyyy hh:mm:ss");
            this.Serie = comprobante.Serie;
            this.Folio = comprobante.Folio;

            //this.FolioFiscal = comprobante.

            this.SubTotal = comprobante.SubTotal;
            if (comprobante.Impuestos != null && comprobante.Impuestos.TotalImpuestosTrasladados.HasValue)
                this.IVA = comprobante.Impuestos.TotalImpuestosTrasladados.Value;
            this.Total = comprobante.Total;

            CantidadEnLetraConverter letraConverter = new CantidadEnLetraConverter();
            letraConverter.Numero = comprobante.Total;
            this.TotalLetra = letraConverter.letra();

            this.MetodoDePago = comprobante.MetodoDePago;
            this.NumCuenta = comprobante.NumCtaPago;

            this.MainCss = ConfigurationManager.AppSettings["InvoiceMainCss"];
            this.PrintCss = ConfigurationManager.AppSettings["InvoicePrintCss"];

            this.EmisorLogoUrl = comprobante.Emisor.LogoUrl;
            this.EmisorTelefono = comprobante.Emisor.Telefono;
            this.EmisorCorreo = comprobante.Emisor.Correo;
            this.EmisorCifUrl = comprobante.Emisor.CifUrl;

            this.NoOrden = comprobante.ExtendedIntValue1.ToString();
            this.NoCliente = comprobante.ExtendedIntValue2.ToString();

            //this.FechaTimbre
            //this.CadenaSAT = comprobante.GetCadenaSAT();
            //this.CBB
            //this.NumSerieSAT
            this.SelloCFD = comprobante.Sello;
            //this.SelloSAT = comprobante.Complementos.
            foreach (Complemento complemento in comprobante.Complementos) {
                if (complemento is TimbreFiscalDigital) {
                    TimbreFiscalDigital timbre = complemento as TimbreFiscalDigital;
                    this.SelloSAT = timbre.SelloSAT;
                    this.FechaTimbre = timbre.FechaTimbrado.ToString("dd/MM/yyyy hh:mm:ss");
                    this.FolioFiscal = timbre.UUID;                    
                    this.NumSerieSAT = timbre.NoCertificadoSAT;
                    this.CadenaSAT = comprobante.GetCadenaSAT();
                    this.CBB = comprobante.GetQrCode();
                }
            }
        }