public Autorizacion ObtenerAutorizacion()
        {
            string resultadoLogin = "";
            ManagerAutorizaciones managerAuto = new ManagerAutorizaciones( this.configuracion.NombreServicio );
            Autorizacion autorizacion = new Autorizacion();

            if ( managerAuto.VerificarVigencia( this.configuracion ) )
            {
                autorizacion = managerAuto.ObtenerAutorizacionVigente();
            }
            else
            {
                this.VerificarDatosBasicos();
                try
                {
                    this.ChequearConectividad();
                    XmlDocument tra = this.generadorTRA.Crear( this.configuracion );
                    string certificado64 = this.FirmarCertificado( tra, this.configuracion.RutaCertificado );
                    resultadoLogin = this.Autorizar( certificado64 );

                    autorizacion = this.deserializadorDeRespuestaLogin.Deserializar( resultadoLogin );

                    managerAuto.SerializarVigencia( autorizacion );
                }
                catch ( Exception error )
                {
                    this.manejadorErrores.ManejarError( error, "ObtenerAutorizacion", error.Message );
                }
            }

            return autorizacion;
        }
        public CAERespuestaFex ObtenerCae( Autorizacion aut, FexCabecera cabFex )
        {
            ClsFEXAuthRequest feAut = this.ObtenerFeAuthReq( aut );
            CAERespuestaFex respuesta = this.SolicitarCAE( cabFex, feAut );

            return respuesta;
        }
        public double ConsultarCotizacion( Autorizacion aut, string idMoneda )
        {
            ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );
            FEXResponse_Ctz respuesta = this.wsfe.FEXGetPARAM_Ctz( feAutRequest, idMoneda );
            this.managerErrores.CapturarError( respuesta.FEXErr );

            return (double) respuesta.FEXResultGet.Mon_ctz;
        }
        public double ConsultarCotizacion( Autorizacion aut, string idMoneda )
        {
            FEAuthRequest feAutRequest = this.wa.ConvertirFe( aut );
            FECotizacionResponse respuesta = this.wsfe.FEParamGetCotizacion( feAutRequest, idMoneda );
            this.managerErrores.CapturarError( respuesta.Errors );

            return respuesta.ResultGet.MonCotiz;
        }
        public int CantidadMaximaDeRegistrosSolicitud( Autorizacion aut )
        {
            FEAuthRequest feAutRequest = this.wa.ConvertirFe( aut );
            FERegXReqResponse respuesta = this.wsfe.FECompTotXRequest( feAutRequest );
            this.managerErrores.CapturarError( respuesta.Errors );

            return respuesta.RegXReq;
        }
        public ClsFEXAuthRequest ConvertirFex( Autorizacion aut )
        {
            ClsFEXAuthRequest feAutReq = new ClsFEXAuthRequest();
            feAutReq.Sign = aut.Sign;
            feAutReq.Token = aut.Token;
            feAutReq.Cuit = aut.Cuit;

            return feAutReq;
        }
        public FEAuthRequest ConvertirFe( Autorizacion aut )
        {
            FEAuthRequest feAutReq = new FEAuthRequest();
            feAutReq.Sign = aut.Sign;
            feAutReq.Token = aut.Token;
            feAutReq.Cuit = aut.Cuit;

            return feAutReq;
        }
        public CAEConsulta ConsultarCAEOtorgado( Autorizacion aut, int periodo, short orden )
        {
            FEAuthRequest feAutRequest = this.wa.ConvertirFe( aut );
            FECAEAGetResponse respuesta = this.wsfe.FECAEAConsultar( feAutRequest, periodo, orden );
            this.managerErrores.CapturarError( respuesta.Errors );
            WrapperCaeConsulta wcc = new WrapperCaeConsulta();

            return wcc.Convertir( respuesta.ResultGet );
        }
        public AuthRequestType ConvertirMTXCA( Autorizacion aut )
        {
            AuthRequestType feAutReq = new AuthRequestType();
            feAutReq.sign = aut.Sign;
            feAutReq.token = aut.Token;
            feAutReq.cuitRepresentada = aut.Cuit;

            return feAutReq;
        }
        public string ObtenerCodigoComprobante( Autorizacion aut, int idTipoComprobante )
        {
            List<IValorRespuestaWS> comprobantes = this.ObtenerTiposDeComprobante( aut );
            IEnumerable<IValorRespuestaWS> retorno = from p in comprobantes
                where p.ObtenerId().Equals( idTipoComprobante.ToString() )
                    select p;

            return retorno.ElementAt( 0 ).Descripcion;
        }
        public CAECabeceraRespuesta ConvertirCabecera( FeCabecera feCab, Autorizacion feAut )
        {
            CAECabeceraRespuesta caeCab = new CAECabeceraRespuesta();
            caeCab.PuntoDeVenta = feCab.PuntoDeVenta;
            caeCab.TipoComprobante = feCab.TipoComprobante;
            caeCab.CantidadDeRegistros = feCab.CantidadDeRegistros;
            caeCab.Cuit = feAut.Cuit;

            return caeCab;
        }
        /// <summary>
        /// Obtiene informacion de respuesta de autorizacion para un comprobante
        /// </summary>
        /// <param name="aut">Autorizacion</param>
        /// <param name="tipoComprobante">Tipo de Comprobante</param>
        /// <param name="nroComprobante">Nro de Comprobante</param>
        /// <param name="ptoVta">Punto de Venta</param>
        /// <returns>Respuesta simil a la de solicitud de CAE</returns>
        public ClsFEXGetCMPR DatosDeComprobante( Autorizacion aut, int tipoComprobante, long nroComprobante, int ptoVta )
        {
            ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );
            ClsFEXGetCMP solicitud = new ClsFEXGetCMP();
            solicitud.Cbte_nro = nroComprobante;
            solicitud.Cbte_tipo = (short)tipoComprobante;
            solicitud.Punto_vta = (short)ptoVta;
            FEXGetCMPResponse  respuesta = this.wsfe.FEXGetCMP( feAutRequest, solicitud );
            this.managerErrores.CapturarError( respuesta.FEXErr );

            return respuesta.FEXResultGet;
        }
        public Autorizacion Deserializar( string resultadoLogin )
        {
            Autorizacion autorizacion = new Autorizacion();

            XmlDocument xml = new XmlDocument();
            xml.LoadXml( resultadoLogin );

            autorizacion.Sign = xml.SelectSingleNode( "//sign" ).InnerText;
            autorizacion.Token = xml.SelectSingleNode( "//token" ).InnerText;
            autorizacion.Cuit = this.configuracion.Cuit;
            autorizacion.Expiracion = Convert.ToDateTime( xml.SelectSingleNode( "//expirationTime" ).InnerText );

            return autorizacion;
        }
        public CAERespuestaFe ObtenerCae( FeCabecera cabFe, Autorizacion aut )
        {
            if ( aut == null )
            {
                ArgumentNullException ex = new ArgumentNullException( "aut", "Se debe indicar una autorización" );
                throw ex;
            }

            AuthRequestType feAut = this.ObtenerAuthReq( aut );

            CAERespuestaFe respuesta = this.SolicitarCAE( cabFe, feAut );

            return respuesta;
        }
        public override List<IValorRespuestaWS> ObtenerTiposDeComprobante( Autorizacion aut )
        {
            AuthRequestType feAutRequest = this.wa.ConvertirMTXCA( aut );
            CodigoDescripcionType evento;
            CodigoDescripcionType[] comprobantes = this.ws.consultarTiposComprobante( feAutRequest, out evento );

            List<IValorRespuestaWS> tiposComprobante = new List<IValorRespuestaWS>();
            Comprobante comprobante;
            foreach ( CodigoDescripcionType comp in comprobantes )
            {
                comprobante = new Comprobante();
                comprobante.Id = comp.codigo;
                comprobante.Descripcion = comp.descripcion;
                tiposComprobante.Add( comprobante );
            }

            return tiposComprobante;
        }
        public CAERespuestaFex ObtenerCaeWSFEX( Autorizacion autorizacion, FexCabecera cabFex )
        {
            long ultimoNro = this.UltimoComprobanteFex( autorizacion, cabFex.PuntoDeVenta, cabFex.TipoComprobante );

            WrapperCabeceraFex wr = new WrapperCabeceraFex();

            ServidorFacturaElectronicaExportacion sfex = new ServidorFacturaElectronicaExportacion( this.wsfex, this.logueador );
            CAERespuestaFex respuesta = null;
            cabFex.Id = this.ObtenerIdFex( cabFex, ultimoNro, autorizacion );
            List<Observacion> diferencias;
            try
            {
                this.logueador.Loguear( "Consultando Afip....." );
                this.logueador.Loguear( cabFex.Serializar() );

                respuesta = sfex.ObtenerCae( autorizacion, cabFex );

                this.logueador.Loguear( "Respuesta Afip......." );
                this.logueador.Loguear( respuesta.Serializar() );

                if ( cabFex.ComprobanteNumero <= ultimoNro )
                {
                    ConsultasWSFex consulta = new ConsultasWSFex( wsfex );
                    ClsFEXGetCMPR comprobanteAfip = consulta.DatosDeComprobante( autorizacion, cabFex.TipoComprobante, cabFex.ComprobanteNumero, cabFex.PuntoDeVenta );
                    // Aca comparo los comprobantes y y si hay diferencias lo rechazo
                    diferencias = wr.Comparar( comprobanteAfip, cabFex );

                    if ( diferencias.Count > 0 )
                    {
                        respuesta.MotivosObservaciones = "Diferencias en comprobante.";
                        respuesta.Observaciones = diferencias;
                        respuesta.Resultado = "R";
                        respuesta.Cae = "";
                    }
                }
            }
            catch ( ExcepcionFe ex )
            {
                this.MensajeDeError = ex.Message;
                throw ex;
            }

            return respuesta;
        }
 public List<Pais> ObtenerCodigosPaises( Autorizacion aut )
 {
     ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );
     FEXResponse_DST_pais respuesta = this.wsfe.FEXGetPARAM_DST_pais( feAutRequest );
     this.managerErrores.CapturarError( respuesta.FEXErr );
     List<Pais> paises = new List<Pais>();
     Pais pais;
     foreach ( ClsFEXResponse_DST_pais respuPais in respuesta.FEXResultGet )
     {
         if ( respuPais != null )
         {
             pais = new Pais();
             pais.Id = respuPais.DST_Codigo;
             pais.Descripcion = respuPais.DST_Ds;
             paises.Add( pais );
         }
     }
     return paises;
 }
        public override CAEDetalleRespuesta DatosDeComprobante( Autorizacion aut, int tipoComprobante, int nroComprobante, int ptoVta )
        {
            AuthRequestType feAutRequest = this.wa.ConvertirMTXCA( aut );
            ConsultaComprobanteRequestType solicitud = new ConsultaComprobanteRequestType();
            solicitud.numeroComprobante = nroComprobante;
            solicitud.codigoTipoComprobante = (short) tipoComprobante;
            solicitud.numeroPuntoVenta = (short) ptoVta;

            CodigoDescripcionType[] observaciones;
            CodigoDescripcionType[] errores;
            CodigoDescripcionType evento;

            ComprobanteType respuesta = this.ws.consultarComprobante( feAutRequest, solicitud, out observaciones, out errores, out evento );
            this.managerErrores.CapturarError( errores );

            ConversorConsultaCaeARespuestaCae conversor = new ConversorConsultaCaeARespuestaCae();
            CAEDetalleRespuesta respuestaConvertida = conversor.ConvertirDetalle( respuesta );

            return respuestaConvertida;
        }
        public List<UltimoNumeroComprobante> NumeracionPorComprobantes( Autorizacion autorizacion, int puntoDeVenta )
        {
            List<UltimoNumeroComprobante> retorno = new List<UltimoNumeroComprobante>();
            try
            {
                IList<IValorRespuestaWS> comprobantes = this.consultas.ObtenerTiposDeComprobante( autorizacion );
                foreach ( Comprobante comprobante in comprobantes )
                {
                    int ultimoNumero = this.consultas.UltimoComprobante( autorizacion, puntoDeVenta, comprobante.Id );

                    retorno.Add( new UltimoNumeroComprobante() { TipoComprobante = comprobante.Id, UltimoNumero = ultimoNumero } );
                }
            }
            catch ( ExcepcionFe error )
            {
                ValidacionException ex = new ValidacionException( "NumeracionPorComprobantes", error.Message );
                this.mensajeDeError = error.Message;
                throw ex;
            }
            return retorno;
        }
        public List<UltimoNumeroComprobante> NumeracionPorComprobantesExportacion( Autorizacion autorizacion, int puntoDeVenta )
        {
            List<UltimoNumeroComprobante> retorno = new List<UltimoNumeroComprobante>();
            ConsultasWSFex consulta = new ConsultasWSFex( this.wsfex );
            try
            {
                List<Comprobante> comprobantes = consulta.ObtenerTiposDeComprobante( autorizacion );
                foreach ( Comprobante comprobante in comprobantes )
                {
                    long ultimoNumero = consulta.UltimoComprobante( autorizacion, puntoDeVenta, comprobante.Id );

                    retorno.Add( new UltimoNumeroComprobante() { TipoComprobante = comprobante.Id, UltimoNumero = (int) ultimoNumero } );
                }
            }
            catch ( ExcepcionFe error )
            {
                ValidacionException ex = new ValidacionException( "NumeracionPorComprobantes", error.Message );
                this.MensajeDeError = error.Message;
                throw ex;
            }
            return retorno;
        }
 public List<CuitPais> ObtenerCuitDePaises( Autorizacion aut )
 {
     ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );
     FEXResponse_DST_cuit respuesta = this.wsfe.FEXGetPARAM_DST_CUIT( feAutRequest );
     this.managerErrores.CapturarError( respuesta.FEXErr );
     List<CuitPais> cuitpaises = new List<CuitPais>();
     CuitPais cuit;
     foreach ( ClsFEXResponse_DST_cuit respuPais in respuesta.FEXResultGet )
     {
         if ( respuPais != null )
         {
             cuit = new CuitPais();
             cuit.Id = respuPais.DST_CUIT;
             cuit.Descripcion = respuPais.DST_Ds;
             cuitpaises.Add( cuit );
         }
     }
     return cuitpaises;
 }
        public long UltimoId( Autorizacion aut )
        {
            ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );

            FEXResponse_LastID respuesta = this.wsfe.FEXGetLast_ID( feAutRequest );
            this.managerErrores.CapturarError( respuesta.FEXErr );

            return respuesta.FEXResultGet.Id;
        }
        /// <summary>
        /// Recibe credenciales de autenticacion, codigo de despacho y pais de destino y verifica la existencia en la base aduanera
        /// </summary>
        /// <param name="aut">Autorizacion en el WSAA</param>
        /// <param name="permisoEmbarque">Codigo de permiso de embarque</param>
        /// <param name="paisDestino">Pais de destino de la mercaderia</param>
        /// <returns></returns>
        public bool PermisoEnAduana( Autorizacion aut, string permisoEmbarque, int paisDestino )
        {
            ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );

            FEXResponse_CheckPermiso respuesta = this.wsfe.FEXCheck_Permiso( feAutRequest, permisoEmbarque, paisDestino );
            this.managerErrores.CapturarError( respuesta.FEXErr );

            return respuesta.FEXResultGet.Status.Equals("OK");
        }
 public List<UnidadDeMedida> ObtenerTiposDeUnidadDeMedida( Autorizacion aut )
 {
     ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );
     FEXResponse_Umed unidadesMedida = this.wsfe.FEXGetPARAM_UMed( feAutRequest );
     this.managerErrores.CapturarError( unidadesMedida.FEXErr );
     List<UnidadDeMedida> tiposunidadesMedida = new List<UnidadDeMedida>();
     UnidadDeMedida unidadMedida;
     foreach ( ClsFEXResponse_UMed umed in unidadesMedida.FEXResultGet )
     {
         if (umed != null)
         {
             unidadMedida = new UnidadDeMedida();
             unidadMedida.Id = umed.Umed_Id;
             unidadMedida.Descripcion = umed.Umed_Ds;
             tiposunidadesMedida.Add(unidadMedida);
         }
     }
     return tiposunidadesMedida;
 }
        public List<TipoMoneda> ObtenerTiposDeMoneda( Autorizacion aut )
        {
            ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );
            FEXResponse_Mon monedas = this.wsfe.FEXGetPARAM_MON( feAutRequest );
            this.managerErrores.CapturarError( monedas.FEXErr );
            List<TipoMoneda> tiposMoneda = new List<TipoMoneda>();
            TipoMoneda tipoMoneda;
            foreach ( ClsFEXResponse_Mon resultado in monedas.FEXResultGet )
            {
                if ( resultado != null )
                {
                    tipoMoneda = new TipoMoneda();
                    tipoMoneda.Id = resultado.Mon_Id;
                    tipoMoneda.Descripcion = resultado.Mon_Ds;
                    tiposMoneda.Add( tipoMoneda );
                }
            }

            return tiposMoneda;
        }
 private ClsFEXAuthRequest ObtenerFeAuthReq( Autorizacion aut )
 {
     WrapperAutorizacion wa = new WrapperAutorizacion();
     return wa.ConvertirFex( aut );
 }
 private AuthRequestType ObtenerAuthReq( Autorizacion aut )
 {
     WrapperAutorizacion wa = new WrapperAutorizacion();
     return wa.ConvertirMTXCA( aut );
 }
        public long UltimoComprobante( Autorizacion aut, int ptovta, int tipo )
        {
            ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );

            ClsFEX_LastCMP x = new ClsFEX_LastCMP();
            x.Token = feAutRequest.Token;
            x.Sign = feAutRequest.Sign;
            x.Cuit = feAutRequest.Cuit;
            x.Pto_venta = (short)ptovta;
            x.Cbte_Tipo = (short)tipo;

            FEXResponseLast_CMP respuesta = this.wsfe.FEXGetLast_CMP( x );
            this.managerErrores.CapturarError( respuesta.FEXErr );

            return respuesta.FEXResult_LastCMP.Cbte_nro;
        }
        public CAERespuestaFe ReprocesarComprobantes( FeCabecera cabFe, Autorizacion feAut )
        {
            ConversorConsultaCaeARespuestaCae conversor = new ConversorConsultaCaeARespuestaCae();
            CAERespuestaFe retorno = new CAERespuestaFe();
            WrapperCabeceraFe wrapperFe = new WrapperCabeceraFe();
            List<Observacion> diferencias;

            retorno.Cabecera = conversor.ConvertirCabecera( cabFe, feAut );

            ConsultasWSMTXCA consultas = new ConsultasWSMTXCA( this.wsfe, this.logueador );
            CAEDetalleRespuesta respuestaReproceso;
            retorno.Detalle = new List<CAEDetalleRespuesta>();

            foreach ( FeDetalle lote in cabFe.DetalleComprobantes )
            {
                respuestaReproceso = consultas.DatosDeComprobante( feAut, cabFe.TipoComprobante, (int) lote.ComprobanteDesde, cabFe.PuntoDeVenta );
                diferencias = wrapperFe.Comparar( respuestaReproceso, lote );

                if ( diferencias.Count > 0 )
                {
                    respuestaReproceso.Resultado = "R";
                    respuestaReproceso.Cae = "";
                    respuestaReproceso.Observaciones = diferencias;
                }
                retorno.Detalle.Add( respuestaReproceso );
            }
            this.logueador.LoguearObservaciones( retorno.Detalle, cabFe );

            return retorno;
        }
        public List<TipoExportacion> ObtenerTiposDeExportacion( Autorizacion aut )
        {
            ClsFEXAuthRequest feAutRequest = this.wa.ConvertirFex( aut );

            FEXResponse_Tex conceptos = this.wsfe.FEXGetPARAM_Tipo_Expo( feAutRequest );
            this.managerErrores.CapturarError( conceptos.FEXErr );
            List<TipoExportacion> tiposExportacion = new List<TipoExportacion>();
            TipoExportacion exportacion;
            foreach ( ClsFEXResponse_Tex comp in conceptos.FEXResultGet )
            {
                if ( comp != null )
                {
                    exportacion = new TipoExportacion();
                    exportacion.Id = comp.Tex_Id;
                    exportacion.Descripcion = comp.Tex_Ds;
                    tiposExportacion.Add( exportacion );
                }
            }
            return tiposExportacion;
        }