/// <summary>
        /// Forma el envío de la factura usando como receptor el rut del cliente. El nuevo archivo es guardado con la extensión .cliente.xml
        /// Debe existir un archivo xml enviado al SII y aceptado por el SII
        /// </summary>
        /// <param name="cfd"></param>
        /// <param name="cfdsFabricados"></param>
        private void ConstruyeEnvioAlCliente(CFDComprobanteFiscalDigital cfd, CFDComprobanteFiscalDigitalFabrica cfdsFabricados)
        {
            try
            {
                XmlDocument xDteParaCliente = new XmlDocument();
                xDteParaCliente.PreserveWhitespace = true;

                String rutaYNomArchivo = cfd.mensaje;
                String dteEnviadoAlSii = "";
                using (StreamReader sr = new StreamReader(rutaYNomArchivo, cfdsFabricados.encodig))
                {
                    dteEnviadoAlSii = sr.ReadToEnd();
                }
                xDteParaCliente.LoadXml(dteEnviadoAlSii);

                XPathNavigator navigator = xDteParaCliente.CreateNavigator();

                XmlNamespaceManager nsManager = new XmlNamespaceManager(navigator.NameTable);
                nsManager.AddNamespace("env", "http://www.sii.cl/SiiDte");
                nsManager.AddNamespace("sig", "http://www.w3.org/2000/09/xmldsig#");

                //Reemplaza el rut del SII por el rut del cliente
                foreach (XPathNavigator nav in navigator.Select("//env:Caratula/env:RutReceptor", nsManager))
                {
                    if (nav.Value.Equals(_rutSII))
                    {
                        nav.SetValue(cfd.idCliente);
                    }
                }

                XmlNodeList nodes = xDteParaCliente.SelectNodes("//env:EnvioDTE/sig:Signature", nsManager);
                //Quita el nodo Signature del envío
                foreach (XmlNode node in nodes)
                {
                    node.RemoveAll();
                    break;
                }
                String sDteParaCliente = xDteParaCliente.InnerXml.Replace("<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"></Signature>", String.Empty);
                xDteParaCliente.LoadXml(sDteParaCliente);

                //Firma el nuevo envío
                XmlAttribute idAFirmar = (XmlAttribute)xDteParaCliente.SelectSingleNode("//env:EnvioDTE/env:SetDTE/@ID", nsManager);
                cfdsFabricados.ModeloEnvio             = new EnvioDteModel();
                cfdsFabricados.ModeloEnvio.setId       = idAFirmar.Value;
                cfdsFabricados.ModeloEnvio.xDocXml     = xDteParaCliente;
                cfdsFabricados.ModeloEnvio.criptografo = cfdsFabricados.encriptador;
                cfdsFabricados.firmaEnvio();

                String rutaYNomArchivoCliente = rutaYNomArchivo.Replace(".xml", ".cliente.xml");
                CustomXmlTextWriter tw        = new CustomXmlTextWriter(rutaYNomArchivoCliente, cfdsFabricados.encodig.WebName.ToUpper());
                cfdsFabricados.ModeloEnvio.xDocXml.Save(tw);
                tw.Close();
            }
            catch (Exception ce)
            {
                _sMsj = "Excepción al formar el envío al cliente. " + ce.Message + " [CFDServicioDespachoSolicitudes.ConstruyeEnvioAlCliente]";
                _iErr++;
            }
        }
        private CFDComprobanteFiscalDigital preparaDte(vwCfdTransaccionesDeVenta loteCfds, XmlDocument autorizacion)
        {
            iErr = 0;
            sMsj = String.Empty;
            CFDComprobanteFiscalDigital cfd = new CFDComprobanteFiscalDigital(_Conex, _Param, _encoding, loteCfds.EstadoActual, loteCfds.IdxSingleStatus, loteCfds.Voidstts,
                                                                              loteCfds.Sopnumbe, loteCfds.Soptype, loteCfds.IdImpuestoCliente, loteCfds.CUSTNMBR, loteCfds.NombreCliente, loteCfds.Doctype);

            cfd.modeloDte.AutorizacionXml = autorizacion;
            cfd.modeloDte.criptografo     = _encriptador;
            cfd.fechaHora = loteCfds.Fechahora;
            iErr         += cfd.iErr;
            sMsj          = cfd.sMsj;

            if (iErr == 0)
            {
                cfd.cicloDeVida.Transiciona(Maquina.eventoEnsamblaLote, _certificados.firma);
                iErr = cfd.cicloDeVida.iErr;
                sMsj = cfd.cicloDeVida.sMsj;
            }

            if (iErr == 0)
            {
                cfd.ensamblaCfd(loteCfds);
                iErr = cfd.iErr;
                sMsj = cfd.sMsj;
            }

            if (iErr == 0)
            {
                //genera el código de barras y guarda el archivo jpg
                cfd.GuardaCodigoBarras();
                iErr = cfd.iErr;
                sMsj = cfd.sMsj;
            }
            if (iErr == 0)
            {
                //registra log de la emisión de factura antes de la impresión
                cfd.Guarda();
                iErr = cfd.iErr;
                sMsj = cfd.sMsj;
            }

            if (iErr == 0)
            {
                cfd.GuardaPdf("B");                                     //B: Original y copia en un solo pdf
                iErr = cfd.iErr;
                sMsj = cfd.sMsj;

                if (sMsj.Contains("Crystal"))                           //no está instalado crystal reports. Se puede continuar pero luego de instalar crystal se debe generar los pdfs
                {
                    iErr = 0;
                    sMsj = "Advertencia. No se ha generado el pdf. " + sMsj;
                }
            }

            return(cfd);
        }
        /// <summary>
        /// Carga en una lista los dte que ha marcado el usuario. No incluye el xml, sólo la ruta donde está guardado.
        /// </summary>
        /// <param name="loteCfds">Lote de documentos a procesar</param>
        public void cargaLote(vwCfdTransaccionesDeVenta loteCfds, int evento)
        {
            try
            {
                OnProgreso(1, "Preparando comprobantes...");        //Notifica al suscriptor

                loteCfds.Rewind();                                  //move to first record

                sMsj = string.Empty;
                iErr = 0;
                int iMaxErr = 0;
                //string docIdAnterior = string.Empty;
                CFDComprobanteFiscalDigital cfd;
                _lDocumentos.Clear();
                do
                {
                    cfd = new CFDComprobanteFiscalDigital(_Conex, _Param, _encoding, loteCfds.EstadoActual, loteCfds.IdxSingleStatus, loteCfds.Voidstts,
                                                          loteCfds.Sopnumbe, loteCfds.Soptype, loteCfds.IdImpuestoCliente, loteCfds.CUSTNMBR, loteCfds.NombreCliente, loteCfds.Doctype);
                    cfd.rutaXml = loteCfds.RutaXml;
                    cfd.mensaje = loteCfds.Mensaje;
                    iErr       += cfd.iErr;

                    if (iErr == 0)
                    {
                        cfd.cicloDeVida.Transiciona(evento, _certificados.envia);
                        iErr = cfd.cicloDeVida.iErr;
                        sMsj = cfd.cicloDeVida.sMsj;
                    }

                    if (iErr == 0)
                    {
                        _lDocumentos.Add(cfd);
                    }

                    OnProgreso(100 / loteCfds.RowCount, "Doc: " + loteCfds.Sopnumbe + " " + cfd.sMsj.Trim() + sMsj, cfd.modeloDte.xDocXml.ToString());

                    if (iErr > 0)
                    {
                        iMaxErr++;
                    }
                    sMsj = string.Empty;
                    iErr = 0;
                } while (loteCfds.MoveNext() && iMaxErr < 10);
                OnProgreso(100, _lDocumentos.Count().ToString() + " comprobante(s) preparado(s).");
            }
            catch (Exception errorGral)
            {
                sMsj = "Excepción encontrada al cargar lote de comprobantes. " + errorGral.Message + " [CFDComprobanteFiscalDigitalFabrica.cargaLote] ";
                iErr++;
                OnProgreso(0, sMsj);
            }
        }
        /// <summary>
        /// Agrega nodo DTE firmado
        /// </summary>
        /// <param name="cfd"></param>
        private void agregaDte(CFDComprobanteFiscalDigital cfd)
        {
            XmlNamespaceManager ns = new XmlNamespaceManager(_modeloEnvio.xDocXml.NameTable);

            ns.AddNamespace("x", _modeloEnvio.xDocXml.DocumentElement.NamespaceURI);
            XmlNode nodoEnvio = _modeloEnvio.xDocXml.SelectSingleNode("//x:EnvioDTE/x:SetDTE", ns);

            nodoEnvio.AppendChild(nodoEnvio.OwnerDocument.ImportNode(
                                      cfd.modeloDte.xDocXml.DocumentElement, true));

            //_modeloEnvio.xDocXml.DocumentElement.AppendChild(_modeloEnvio.xDocXml.ImportNode(cfd.modeloDte.xDocXml.DocumentElement, true));
            String sEnvio = _modeloEnvio.xDocXml.OuterXml.Replace("</DTE></SetDTE>", "</DTE>\n</SetDTE>");

            sEnvio = sEnvio.Replace(" xmlns=\"\"", "");
            _modeloEnvio.xDocXml.LoadXml(sEnvio);

            _modeloEnvio.lDocumentos.Add(cfd);
        }
        private void ensamblaEnvio(CFDComprobanteFiscalDigital cfd, string tipoDoc)
        {
            try
            {
                _modeloEnvio = new EnvioDteModel(cfd.modeloDte, _certificados, cfd.rutaXml, _encoding, cfd.sopnumbe);

                _modeloEnvio.criptografo = _encriptador;

                _modeloEnvio.prepara(_lDocumentos, tipoDoc);

                _modeloEnvio.Serializa();

                _modeloEnvio.Canonicaliza(_modeloEnvio.xDocXml);

                reAjustaAtributos();
            }
            catch (Exception)
            {
                throw;
            }
        }
        private void preparaContenedor(CFDComprobanteFiscalDigital cfd)
        {
            cfd.cicloDeVida.Transiciona(Maquina.eventoEnviaAlSII, _certificados.envia);
            iErr = cfd.cicloDeVida.iErr;
            sMsj = cfd.cicloDeVida.sMsj;

            if (iErr == 0)
            {
                ensamblaEnvio(cfd, cfd.modeloDte.dteDoc.Encabezado.IdDoc.TipoDTE.ToString());   //crea un nuevo contenedor

                agregaDte(cfd);

                firmaEnvio();

                if (_modeloEnvio.iErr == 0)
                {
                    _lContenedores.Add(_modeloEnvio);
                }

                iErr = _modeloEnvio.iErr;
                sMsj = _modeloEnvio.sMsj;
            }
        }