diff --git a/lib/fm_timbrado_cfdi.rb b/lib/fm_timbrado_cfdi.rb index 3380192..de22bf5 100644 --- a/lib/fm_timbrado_cfdi.rb +++ b/lib/fm_timbrado_cfdi.rb @@ -1,5 +1,7 @@ require "fm_timbrado_cfdi/version" require "fm_timbrado_cfdi/fm_cliente" +require "fm_timbrado_cfdi/fm_respuesta3_3" +require "fm_timbrado_cfdi/fm_timbre3_3" require "fm_timbrado_cfdi/fm_informacion_cfdi" require 'nokogiri' require 'base64' @@ -51,6 +53,10 @@ def timbrar (rfc, archivo, opciones= {}) cliente.timbrar rfc, archivo, opciones end + def timbrar3_3 (rfc, archivo, opciones= {}) + cliente.timbrar3_3 rfc, archivo, opciones + end + # Public: Envía CSD para que lo almacene el PAC # # rfc - Es el RFC del emisor diff --git a/lib/fm_timbrado_cfdi/fm_cliente.rb b/lib/fm_timbrado_cfdi/fm_cliente.rb index e8911b8..1a2b85a 100644 --- a/lib/fm_timbrado_cfdi/fm_cliente.rb +++ b/lib/fm_timbrado_cfdi/fm_cliente.rb @@ -1,5 +1,6 @@ require 'savon' require 'fm_timbrado_cfdi/fm_respuesta' +require 'fm_timbrado_cfdi/fm_respuesta3_3' require 'fm_timbrado_cfdi/fm_respuesta_cancelacion' module FmTimbradoCfdi @@ -30,6 +31,13 @@ def timbrar(rfc, documento, opciones={}) FmRespuesta.new(respuesta) end + def timbrar3_3(rfc, documento, opciones={}) + text_to_cfdi = Base64::encode64( documento ) + # Realizamos la peticion + respuesta = webservice_call(:request_timbrar_cfdi, rfc, {"text2CFDI" => text_to_cfdi}.merge(opciones)) + FmRespuesta3_3.new(respuesta) + end + def subir_certificado(rfc, certificado, llave, password, opciones = {}) parametros = { "archivoCer" => Base64::encode64(certificado), "archivoKey" => Base64::encode64(llave), diff --git a/lib/fm_timbrado_cfdi/fm_respuesta3_3.rb b/lib/fm_timbrado_cfdi/fm_respuesta3_3.rb new file mode 100644 index 0000000..dc2dd5b --- /dev/null +++ b/lib/fm_timbrado_cfdi/fm_respuesta3_3.rb @@ -0,0 +1,21 @@ +require "fm_timbrado_cfdi/fm_respuesta" +require 'fm_timbrado_cfdi/fm_timbre3_3' + +module FmTimbradoCfdi + class FmRespuesta3_3 < FmRespuesta + + def obtener_timbre(xml) + FmTimbre3_3.new(xml) if xml + end + + def obtener_no_csd_emisor(xml) + begin + factura_xml = Nokogiri::XML(xml) + factura_xml.xpath("//cfdi:Comprobante").attribute('NoCertificado').value + rescue Exception => e + @errors << "No se ha podido obtener el CSD del emisor" + nil + end + end + end +end diff --git a/lib/fm_timbrado_cfdi/fm_timbre3_3.rb b/lib/fm_timbrado_cfdi/fm_timbre3_3.rb new file mode 100644 index 0000000..0085143 --- /dev/null +++ b/lib/fm_timbrado_cfdi/fm_timbre3_3.rb @@ -0,0 +1,38 @@ +require 'fm_timbrado_cfdi/fm_timbre' + +module FmTimbradoCfdi + class FmTimbre3_3 < FmTimbre + def obtener_version(xml,ns) + xml.xpath("//tfd:TimbreFiscalDigital", ns).attribute('Version').value rescue nil + end + + def obtener_no_certificado(xml,ns) + xml.xpath("//cfdi:Comprobante",ns).attribute('NoCertificado').value rescue nil + end + + def obtener_no_certificado_sat(xml, ns) + xml.xpath("//tfd:TimbreFiscalDigital", ns).attribute('NoCertificadoSAT').value rescue nil + end + + def obtener_sello_sat(xml, ns) + xml.xpath("//tfd:TimbreFiscalDigital", ns).attribute('SelloSAT').value rescue nil + end + + def obtener_fecha_comprobante(xml, ns) + xml.xpath("//cfdi:Comprobante", ns).attribute('Fecha').value rescue nil + end + + def obtener_sello_cfd(xml, ns) + xml.xpath("//tfd:TimbreFiscalDigital", ns).attribute('SelloCFD').value rescue nil + end + + def obtener_serie(xml, ns ) + xml.xpath("//cfdi:Comprobante", ns).attribute('Serie').value rescue nil + end + + def obtener_folio(xml, ns) + xml.xpath("//cfdi:Comprobante", ns).attribute('Folio').value rescue nil + end + end +end + diff --git a/spec/fixtures/layout_example3_3.txt b/spec/fixtures/layout_example3_3.txt new file mode 100644 index 0000000..7288e6b --- /dev/null +++ b/spec/fixtures/layout_example3_3.txt @@ -0,0 +1,69 @@ +[ComprobanteFiscalDigital] +Version=3.3 +Serie=A +Folio=01 +Fecha=--fecha-comprobante-- +FormaPago=03 +CondicionesDePago=CONTADO +SubTotal=1850.00 +Descuento=175.00 +Moneda=MXN +Total=1943.00 +TipoDeComprobante=I +MetodoPago=PUE +LugarExpedicion=68050 + +[DatosAdicionales] +tipoDocumento=FACTURA +observaciones=Observaciones al documento versión 3.3 +platillaPDF=clasic + +[Emisor] +Rfc=ESI920427886 +Nombre=FACTURACION MODERNA SA DE CV +RegimenFiscal=601 + +[Receptor] +Rfc=AAQM610917QJA +Nombre=PUBLICO EN GENERAL +UsoCFDI=G01 + +[Concepto#1] +ClaveProdServ=01010101 +NoIdentificacion=AULOG001 +Cantidad=5 +ClaveUnidad=H87 +Unidad=Pieza +Descripcion=Aurriculares USB Logitech +ValorUnitario=350.00 +Importe=1750.00 +Descuento=175.00 + +Impuestos.Traslados.Base=[1575.00] +Impuestos.Traslados.Impuesto=[002] +Impuestos.Traslados.TipoFactor=[Tasa] +Impuestos.Traslados.TasaOCuota=[0.160000] +Impuestos.Traslados.Importe=[252.00] + +[Concepto#2] +ClaveProdServ=43201800 +NoIdentificacion=USB +Cantidad=1 +ClaveUnidad=H87 +Unidad=Pieza +Descripcion=Memoria USB 32gb marca Kingston +ValorUnitario=100.00 +Importe=100.00 + +Impuestos.Traslados.Base=[100.00] +Impuestos.Traslados.Impuesto=[002] +Impuestos.Traslados.TipoFactor=[Tasa] +Impuestos.Traslados.TasaOCuota=[0.160000] +Impuestos.Traslados.Importe=[16.00] + +[Traslados] +TotalImpuestosTrasladados=268.00 +Impuesto=[002] +TipoFactor=[Tasa] +TasaOCuota=[0.160000] +Importe=[268.00] diff --git a/spec/fixtures/soap_response3_3.txt b/spec/fixtures/soap_response3_3.txt new file mode 100644 index 0000000..930f483 --- /dev/null +++ b/spec/fixtures/soap_response3_3.txt @@ -0,0 +1,2 @@ + +PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPGNmZGk6Q29tcHJvYmFudGUgeG1sbnM6Y2ZkaT0iaHR0cDovL3d3dy5zYXQuZ29iLm14L2NmZC8zIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3d3dy5zYXQuZ29iLm14L2NmZC8zIGh0dHA6Ly93d3cuc2F0LmdvYi5teC9zaXRpb19pbnRlcm5ldC9jZmQvMy9jZmR2MzMueHNkIiBWZXJzaW9uPSIzLjMiIFNlcmllPSJBIiBGb2xpbz0iMDEiIEZlY2hhPSIyMDE3LTA3LTAzVDE2OjI5OjU1IiBTZWxsbz0icmZrNkk4VTJOb3VqWTBTMzRGa0RJemNIQUNwRVMyOWdXSWcvcTVVWlB0VEt6UHRZcituQkhHWkUzL2dYZDRrcFJSMHdxMHZaQkhyUllCL05UTWVNQlVIV2haSUw0NE81MldVK0hENkk2Q2pHZjVpb0xiSnFoS2cvakgzSGNmWUxBYTV1NHRrZjMzRUtNbHBaV1lVckpTMFlUQ29UM0REQ2ZlLzNrT0l6YnI4PSIgRm9ybWFQYWdvPSIwMyIgTm9DZXJ0aWZpY2Fkbz0iMjAwMDEwMDAwMDAyMDAwMDAxOTIiIENlcnRpZmljYWRvPSJNSUlFUmpDQ0F5NmdBd0lCQWdJVU1qQXdNREV3TURBd01EQXlNREF3TURBeE9USXdEUVlKS29aSWh2Y05BUUVGQlFBd2dnRmNNUm93R0FZRFZRUUREQkZCTGtNdUlESWdaR1VnY0hKMVpXSmhjekV2TUMwR0ExVUVDZ3dtVTJWeWRtbGphVzhnWkdVZ1FXUnRhVzVwYzNSeVlXTnB3N051SUZSeWFXSjFkR0Z5YVdFeE9EQTJCZ05WQkFzTUwwRmtiV2x1YVhOMGNtRmphY096YmlCa1pTQlRaV2QxY21sa1lXUWdaR1VnYkdFZ1NXNW1iM0p0WVdOcHc3TnVNU2t3SndZSktvWklodmNOQVFrQkZocGhjMmx6Ym1WMFFIQnlkV1ZpWVhNdWMyRjBMbWR2WWk1dGVERW1NQ1FHQTFVRUNRd2RRWFl1SUVocFpHRnNaMjhnTnpjc0lFTnZiQzRnUjNWbGNuSmxjbTh4RGpBTUJnTlZCQkVNQlRBMk16QXdNUXN3Q1FZRFZRUUdFd0pOV0RFWk1CY0dBMVVFQ0F3UVJHbHpkSEpwZEc4Z1JtVmtaWEpoYkRFU01CQUdBMVVFQnd3SlEyOTViMkZqdzZGdU1UUXdNZ1lKS29aSWh2Y05BUWtDRENWU1pYTndiMjV6WVdKc1pUb2dRWEpoWTJWc2FTQkhZVzVrWVhKaElFSmhkWFJwYzNSaE1CNFhEVEV5TVRBeU1qSXdORGd3TmxvWERURTJNVEF5TWpJd05EZ3dObG93Z2NBeElUQWZCZ05WQkFNVEdFVkVTVlJQVWtsQlRDQlRTVk5VUVNCVFFTQkVSU0JEVmpFaE1COEdBMVVFS1JNWVJVUkpWRTlTU1VGTUlGTkpVMVJCSUZOQklFUkZJRU5XTVNFd0h3WURWUVFLRXhoRlJFbFVUMUpKUVV3Z1UwbFRWRUVnVTBFZ1JFVWdRMVl4SlRBakJnTlZCQzBUSEVWVFNUa3lNRFF5TnpnNE5pQXZJRWhGUjFRM05qRXdNRE0wVXpJeEhqQWNCZ05WQkFVVEZTQXZJRWhGUjFRM05qRXdNRE5OUkVaU1RrNHdPVEVPTUF3R0ExVUVDeE1GUVcxcFoyRXdnWjh3RFFZSktvWklodmNOQVFFQkJRQURnWTBBTUlHSkFvR0JBSzZZcUFnM0xIT1BwQUtEOU9Ga2NOZ0I1d2orM2s0b0hQSzNiRmZrdTRUQ0Vzd3RNaEl0NUxuWkN0NFVLMGNwOVNZcEtNYTJrWlZZbTZrNnpwaFdnOWJ6djNwdkh3dDltQjZrRkd5QXBVNzFjT2sxNnVucUwyby9wRGo2NXpOdFVCZkR5S2tLQlVHUU1ZZ3RxdlZxNmFYSmlwcUtPUy9Oc0RLRVV0MHExZ2hUQWdNQkFBR2pIVEFiTUF3R0ExVWRFd0VCL3dRQ01BQXdDd1lEVlIwUEJBUURBZ2JBTUEwR0NTcUdTSWIzRFFFQkJRVUFBNElCQVFDZ0NDcFlEYm1OOG5wTFg2dkhDRUpBRi8xRzNLaHVBR1k0OHdWdDF2YTFZWFJ5NnlqK3RKWjlIWjNsOFRZN0o2bjEwWGtyYnplZE9Bckt5amRwZnFXYk5hYlpIdzZiMklsU044SHJIbGlpQUVvcjVod1RVSm5rZzZTMW5tMG1taXJJbnhDbVdvVlYrcXJFWC9YSHlsSitPaklxbC9HeVpySDlzRVBDWStMWUZmVmhPMFU3M2pLcWFqTUVlWnRXWXE1d3JvNFVoUFVobFlnd2hselVONlhOV3RpQzhvaGpFNlFKYWY4allSc0pqSHJhWkwyNTdPMW81VC8zVUxNSmhBU043UjIxMUZteUF1aVlzcThIM2J1UEUwa2wrRW1OOERVTnBURGtCOVhmMWJhNmdYWjBQUlhGMW9HVXd4dlg5RmlJNWVJYXUyUkxmeTlBZkpQY3BBWE4iIENvbmRpY2lvbmVzRGVQYWdvPSJDT05UQURPIiBTdWJUb3RhbD0iMTg1MC4wMCIgRGVzY3VlbnRvPSIxNzUuMDAiIE1vbmVkYT0iTVhOIiBUb3RhbD0iMTk0My4wMCIgVGlwb0RlQ29tcHJvYmFudGU9IkkiIE1ldG9kb1BhZ289IlBVRSIgTHVnYXJFeHBlZGljaW9uPSI2ODA1MCI+CiAgPGNmZGk6RW1pc29yIFJmYz0iRVNJOTIwNDI3ODg2IiBOb21icmU9IkZBQ1RVUkFDSU9OIE1PREVSTkEgU0EgREUgQ1YiIFJlZ2ltZW5GaXNjYWw9IjYwMSIvPgogIDxjZmRpOlJlY2VwdG9yIFJmYz0iQUFRTTYxMDkxN1FKQSIgTm9tYnJlPSJQVUJMSUNPIEVOIEdFTkVSQUwiIFVzb0NGREk9IkcwMSIvPgogIDxjZmRpOkNvbmNlcHRvcz4KICAgIDxjZmRpOkNvbmNlcHRvIENsYXZlUHJvZFNlcnY9IjAxMDEwMTAxIiBOb0lkZW50aWZpY2FjaW9uPSJBVUxPRzAwMSIgQ2FudGlkYWQ9IjUiIENsYXZlVW5pZGFkPSJIODciIFVuaWRhZD0iUGllemEiIERlc2NyaXBjaW9uPSJBdXJyaWN1bGFyZXMgVVNCIExvZ2l0ZWNoIiBWYWxvclVuaXRhcmlvPSIzNTAuMDAiIEltcG9ydGU9IjE3NTAuMDAiIERlc2N1ZW50bz0iMTc1LjAwIj4KICAgICAgPGNmZGk6SW1wdWVzdG9zPgogICAgICAgIDxjZmRpOlRyYXNsYWRvcz4KICAgICAgICAgIDxjZmRpOlRyYXNsYWRvIEJhc2U9IjE1NzUuMDAiIEltcHVlc3RvPSIwMDIiIFRpcG9GYWN0b3I9IlRhc2EiIFRhc2FPQ3VvdGE9IjAuMTYwMDAwIiBJbXBvcnRlPSIyNTIuMDAiLz4KICAgICAgICA8L2NmZGk6VHJhc2xhZG9zPgogICAgICA8L2NmZGk6SW1wdWVzdG9zPgogICAgPC9jZmRpOkNvbmNlcHRvPgogICAgPGNmZGk6Q29uY2VwdG8gQ2xhdmVQcm9kU2Vydj0iNDMyMDE4MDAiIE5vSWRlbnRpZmljYWNpb249IlVTQiIgQ2FudGlkYWQ9IjEiIENsYXZlVW5pZGFkPSJIODciIFVuaWRhZD0iUGllemEiIERlc2NyaXBjaW9uPSJNZW1vcmlhIFVTQiAzMmdiIG1hcmNhIEtpbmdzdG9uIiBWYWxvclVuaXRhcmlvPSIxMDAuMDAiIEltcG9ydGU9IjEwMC4wMCI+CiAgICAgIDxjZmRpOkltcHVlc3Rvcz4KICAgICAgICA8Y2ZkaTpUcmFzbGFkb3M+CiAgICAgICAgICA8Y2ZkaTpUcmFzbGFkbyBCYXNlPSIxMDAuMDAiIEltcHVlc3RvPSIwMDIiIFRpcG9GYWN0b3I9IlRhc2EiIFRhc2FPQ3VvdGE9IjAuMTYwMDAwIiBJbXBvcnRlPSIxNi4wMCIvPgogICAgICAgIDwvY2ZkaTpUcmFzbGFkb3M+CiAgICAgIDwvY2ZkaTpJbXB1ZXN0b3M+CiAgICA8L2NmZGk6Q29uY2VwdG8+CiAgPC9jZmRpOkNvbmNlcHRvcz4KICA8Y2ZkaTpJbXB1ZXN0b3MgVG90YWxJbXB1ZXN0b3NUcmFzbGFkYWRvcz0iMjY4LjAwIj4KICAgIDxjZmRpOlRyYXNsYWRvcz4KICAgICAgPGNmZGk6VHJhc2xhZG8gSW1wdWVzdG89IjAwMiIgVGlwb0ZhY3Rvcj0iVGFzYSIgVGFzYU9DdW90YT0iMC4xNjAwMDAiIEltcG9ydGU9IjI2OC4wMCIvPgogICAgPC9jZmRpOlRyYXNsYWRvcz4KICA8L2NmZGk6SW1wdWVzdG9zPgogIDxjZmRpOkNvbXBsZW1lbnRvPgogICAgPHRmZDpUaW1icmVGaXNjYWxEaWdpdGFsIHhtbG5zOnRmZD0iaHR0cDovL3d3dy5zYXQuZ29iLm14L1RpbWJyZUZpc2NhbERpZ2l0YWwiIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3d3dy5zYXQuZ29iLm14L1RpbWJyZUZpc2NhbERpZ2l0YWwgaHR0cDovL3d3dy5zYXQuZ29iLm14L3NpdGlvX2ludGVybmV0L2NmZC9UaW1icmVGaXNjYWxEaWdpdGFsL1RpbWJyZUZpc2NhbERpZ2l0YWx2MTEueHNkIiBWZXJzaW9uPSIxLjEiIFVVSUQ9Ijk1ODhFQjQ1LUNCRDgtNDQ1RC05RTlCLUY5RUI0RkQ4NzZDNyIgRmVjaGFUaW1icmFkbz0iMjAxNy0wNy0wM1QxNjoyOTo1NyIgUmZjUHJvdkNlcnRpZj0iRk1PMTAwNzE2OEM2IiBTZWxsb0NGRD0icmZrNkk4VTJOb3VqWTBTMzRGa0RJemNIQUNwRVMyOWdXSWcvcTVVWlB0VEt6UHRZcituQkhHWkUzL2dYZDRrcFJSMHdxMHZaQkhyUllCL05UTWVNQlVIV2haSUw0NE81MldVK0hENkk2Q2pHZjVpb0xiSnFoS2cvakgzSGNmWUxBYTV1NHRrZjMzRUtNbHBaV1lVckpTMFlUQ29UM0REQ2ZlLzNrT0l6YnI4PSIgTm9DZXJ0aWZpY2Fkb1NBVD0iMjAwMDEwMDAwMDAzMDAwMjIzMjMiIFNlbGxvU0FUPSJjWkZtaXBYWU1oclhmcGthMlBSM2NHWERXM1RUWTFMU1NJMHEzK1dQbVhmcVQwUU53R0pjRmZiUVZxUGx1c0IxNHdoMkdza2xDeUxuTUREdVNPS2VRRms4SmM4L0ZoN1Y0MTJ2S0puUmZEK0pQNU5pRGRpU3RVWlhTOUxBQ1VYRXo3djFRZXh3OS9OWklyeUZFZXlzdmRxVmQ1SG1WcGdtRysvTkc4R1o0MDdOMGNNcUlGZDk5MkhjVFJJV3FDZmhxZ2pzQ1NmVkhkR0hQRWR3MFdJNDQwcFJXZCs0aEQrcDNkK2JQdnEwZWpCb3RKcFJmTTlLckVZNmFIWEY4bDZvUWZmZVRVQUorM2haZ0hZNWtmeGtadGdvZFpaSzZTUkR0YWtVUm14dW00TXNTbWxDYU9paVNEdkZXZUdQTlV0RzlTcnNvQzc0N1pNeUZiSXV1Nnpyb2c9PSIvPgogIDwvY2ZkaTpDb21wbGVtZW50bz4KPC9jZmRpOkNvbXByb2JhbnRlPgo= diff --git a/spec/fm_timbrado_cfdi/fm_respuesta3_3_spec.rb b/spec/fm_timbrado_cfdi/fm_respuesta3_3_spec.rb new file mode 100644 index 0000000..cdd8294 --- /dev/null +++ b/spec/fm_timbrado_cfdi/fm_respuesta3_3_spec.rb @@ -0,0 +1,35 @@ +# encoding: utf-8 +require 'spec_helper' +require 'ostruct' + +describe FmTimbradoCfdi::FmRespuesta3_3 do + context "respuesta no satisfactoria" do + let(:respuesta_cliente) do + prueba = OpenStruct.new + prueba.stub(:success?).and_return(false) + prueba.stub_chain(:soap_fault?).and_return(true) + prueba.stub_chain(:soap_fault, :to_s).and_return('Test Error') + prueba + end + let(:respuesta) { FmTimbradoCfdi::FmRespuesta3_3.new(respuesta_cliente) } + it { expect(respuesta.valid?).to eq(false) } + it { expect(respuesta.xml?).to eq(false) } + it { expect(respuesta.pdf?).to eq(false) } + it { expect(respuesta.cbb?).to eq(false) } + it { expect(respuesta.timbre?).to eq(false) } + it { expect(respuesta.no_csd_emisor?).to eq(false) } + end + + context 'respuesta correcta' do + let(:texto_respuesta){File.open('spec/fixtures/soap_response3_3.txt').read} + let(:respuesta) { FmTimbradoCfdi::FmRespuesta3_3.new(texto_respuesta) } + it { expect(respuesta.valid?).to eq(true) } + end + + context "respuesta sin xml" do + let(:texto_respuesta){File.open('spec/fixtures/soap_response_sin_xml.txt').read} + let(:respuesta) { FmTimbradoCfdi::FmRespuesta3_3.new(texto_respuesta) } + it { expect(respuesta.valid?).to eq(false) } + it { expect(respuesta.errors.first).to eq("No se ha encontrado el nodo xml") } + end +end diff --git a/spec/fm_timbrado_cfdi/fm_timbre3_3_spec.rb b/spec/fm_timbrado_cfdi/fm_timbre3_3_spec.rb new file mode 100644 index 0000000..784d996 --- /dev/null +++ b/spec/fm_timbrado_cfdi/fm_timbre3_3_spec.rb @@ -0,0 +1,17 @@ +# encoding: utf-8 +require 'spec_helper' + +describe FmTimbradoCfdi::FmTimbre3_3 do + context "debe crear un objeto válido" do + let(:plantilla){File.open('spec/fixtures/layout_example3_3.txt').read} + let(:layout){ plantilla.gsub('--fecha-comprobante--', 'asignarFecha' )} + let(:respuesta){ FmTimbradoCfdi.timbrar3_3 'ESI920427886', layout } + let(:timbre) { FmTimbradoCfdi::FmTimbre3_3.new(respuesta.xml)} + it { timbre.no_certificado_sat.should_not be_nil } + it { timbre.fecha_timbrado.should_not be_nil } + it { timbre.uuid.should_not be_nil } + it { timbre.sello_sat.should_not be_nil } + it { timbre.sello_cfd.should_not be_nil } + it { timbre.cadena_original.should_not be_nil } + end +end diff --git a/spec/fm_timbrado_cfdi_spec.rb b/spec/fm_timbrado_cfdi_spec.rb index 61133d2..01bbd4d 100644 --- a/spec/fm_timbrado_cfdi_spec.rb +++ b/spec/fm_timbrado_cfdi_spec.rb @@ -98,6 +98,47 @@ end end + describe ".timbrar" do + context "timbrado correcto" do + context 'archivo de prueba simple' do + let(:plantilla){File.open('spec/fixtures/layout_example3_3.txt').read} + let(:layout){ plantilla.gsub('--fecha-comprobante--', 'asignarFecha' )} + let(:respuesta){ FmTimbradoCfdi.timbrar3_3 'ESI920427886', layout } + it { respuesta.should be_valid } + it { respuesta.should be_xml } + + context "formato cbb" do + let(:respuesta){ FmTimbradoCfdi.timbrar3_3 'ESI920427886', layout, 'generarCBB' => true } + it { respuesta.should be_valid } + it { respuesta.should be_xml } + it { respuesta.should be_cbb } + end + + context "formato txt" do + let(:respuesta){ FmTimbradoCfdi.timbrar3_3 'ESI920427886', layout, 'generarTXT' => true } + it { respuesta.should be_valid } + it { respuesta.should be_xml } + it { respuesta.should be_timbre } + end + + context "formato pdf" do + let(:respuesta){ FmTimbradoCfdi.timbrar3_3 'ESI920427886', layout, 'generarPDF' => true } + it { respuesta.should be_valid } + it { respuesta.should be_xml } + it { respuesta.should be_pdf } + end + + context "formato pdf, pero no cbb, ni txt" do + let(:respuesta){ FmTimbradoCfdi.timbrar3_3 'ESI920427886', layout, 'generarPDF' => true, 'generarCBB' => false, 'generarTXT' => false } + it { respuesta.should be_valid } + it { respuesta.should be_xml } + it { respuesta.should be_pdf } + it { respuesta.should_not be_cbb } + end + end + end + end + context 'subir certificados' do let(:archivo_certificado) { File.read('spec/fixtures/certificados/20001000000200000192.cer') } let(:archivo_llave) { File.read('spec/fixtures/certificados/20001000000200000192.key') }