sw_fac 0.3.58.1 → 0.3.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/sw_fac/config.rb +6 -0
- data/lib/sw_fac/facturacion.rb +274 -23
- data/lib/sw_fac/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff59c51cb10373fbc6e32713380a3f4b375e90f962086d71254ca11075e39ada
|
4
|
+
data.tar.gz: 9add1352a09c499c0201b83d9bd73853494d34e1dab295e8bcd46ed4a205155b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75815faa0da46d83cf5d1aba0e8b730f08a0b76a1ca762c7d9a294e265ea64035d728f7f51c925b4bb714e3b1e31f626d95b58c506ec743d53693038b5ebfc50
|
7
|
+
data.tar.gz: b209ef695f4fe7857801a2d2921f478f2e2a0f1d4de340f43af04dd31454539c06dd06dd5b9d3bd0c37eed0192de8c3227a11a86e43b7f18f4c3390c6e3150b5
|
data/lib/sw_fac/config.rb
CHANGED
@@ -25,7 +25,10 @@ module SwFac
|
|
25
25
|
def key_to_pem
|
26
26
|
puts "---- SwFacturacion:config:key_to_pem"
|
27
27
|
|
28
|
+
puts "-- 1"
|
28
29
|
@pem = %x[openssl pkcs8 -inform DER -in #{@doc_key_path} -passin pass:#{@key_pass}]
|
30
|
+
# @pem = %x[openssl rsa -inform DER -in #{@doc_key_path} -passin pass:#{@key_pass}]
|
31
|
+
puts "-- 2"
|
29
32
|
@pem_cadena = @pem.clone
|
30
33
|
@pem_cadena.slice!("-----BEGIN PRIVATE KEY-----")
|
31
34
|
@pem_cadena.slice!("-----END PRIVATE KEY-----")
|
@@ -74,6 +77,9 @@ module SwFac
|
|
74
77
|
<cfdi:Receptor /><cfdi:Conceptos></cfdi:Conceptos>
|
75
78
|
<cfdi:Impuestos></cfdi:Impuestos></cfdi:Comprobante>)
|
76
79
|
|
80
|
+
DocBaseCero = %(<?xml version="1.0" encoding="utf-8"?><cfdi:Comprobante xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd" Version="3.3" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><cfdi:Emisor />
|
81
|
+
<cfdi:Receptor /><cfdi:Conceptos></cfdi:Conceptos></cfdi:Comprobante>)
|
82
|
+
|
77
83
|
Doc_concepto = %(<cfdi:Concepto ClaveProdServ="25172504" NoIdentificacion="COST37125R17" Cantidad="1" ClaveUnidad="H87" Unidad="Pieza" Descripcion="Producto de prueba" ValorUnitario="1000.00" Importe="1000.00"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base="1000.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="160.00" /></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto>)
|
78
84
|
|
79
85
|
|
data/lib/sw_fac/facturacion.rb
CHANGED
@@ -12,7 +12,8 @@ module SwFac
|
|
12
12
|
# receptor_rfc: 'XAXX010101000',
|
13
13
|
# forma_pago: '01',
|
14
14
|
# total: 100.00,
|
15
|
-
#
|
15
|
+
# time_pago: '',
|
16
|
+
# time_now: '',
|
16
17
|
# modena: '',
|
17
18
|
# line_items: [
|
18
19
|
# {
|
@@ -36,9 +37,16 @@ module SwFac
|
|
36
37
|
raise 'Error SW - la suma de los complementos de pago es mayor al total reportado'
|
37
38
|
end
|
38
39
|
|
40
|
+
unless params[:time_pago] and params[:time_pago].size > 0
|
41
|
+
raise "Error SW - la fecha de timbrado debe de estar presente"
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
39
46
|
uri = @production ? URI("#{SwFac::UrlProduction}cfdi33/stamp/customv1/b64") : URI("#{SwFac::UrlDev}cfdi33/stamp/customv1/b64")
|
40
47
|
token = @production ? @production_token : @dev_token
|
41
|
-
|
48
|
+
time_now = params.fetch(:time_now, (Time.now).strftime("%Y-%m-%dT%H:%M:%S"))
|
49
|
+
time_pago = params[:time_pago]
|
42
50
|
|
43
51
|
|
44
52
|
base_doc = %(<?xml version="1.0" encoding="UTF-8"?>
|
@@ -57,13 +65,13 @@ module SwFac
|
|
57
65
|
</cfdi:Comprobante>)
|
58
66
|
|
59
67
|
base_doc.delete!("\n")
|
60
|
-
|
68
|
+
base_doc.delete!("\t")
|
61
69
|
|
62
|
-
|
70
|
+
xml = Nokogiri::XML(base_doc)
|
63
71
|
comprobante = xml.at_xpath("//cfdi:Comprobante")
|
64
72
|
comprobante['Serie'] = 'P'
|
65
73
|
comprobante['Folio'] = params[:venta_folio].to_s
|
66
|
-
comprobante['Fecha'] =
|
74
|
+
comprobante['Fecha'] = time_now
|
67
75
|
comprobante['LugarExpedicion'] = params[:cp].to_s
|
68
76
|
comprobante['NoCertificado'] = @serial
|
69
77
|
comprobante['Certificado'] = @cadena
|
@@ -76,7 +84,7 @@ module SwFac
|
|
76
84
|
receptor['Rfc'] = params[:receptor_rfc].to_s
|
77
85
|
|
78
86
|
child_pago = xml.at_xpath("//pago10:Pago")
|
79
|
-
child_pago['FechaPago'] =
|
87
|
+
child_pago['FechaPago'] = time_pago
|
80
88
|
child_pago['FormaDePagoP'] = params[:forma_pago].to_s
|
81
89
|
child_pago['MonedaP'] = params.fetch(:moneda, 'MXN')
|
82
90
|
child_pago['Monto'] = params[:total].round(2).to_s
|
@@ -84,19 +92,19 @@ module SwFac
|
|
84
92
|
saldo_anterior = params[:total]
|
85
93
|
|
86
94
|
params[:line_items].each_with_index do |line, index|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
95
|
+
monto = line[:monto].to_f
|
96
|
+
child_pago_relacionado = Nokogiri::XML::Node.new "pago10:DoctoRelacionado", xml
|
97
|
+
child_pago_relacionado['IdDocumento'] = params[:uuid]
|
98
|
+
child_pago_relacionado['MonedaDR'] = line.fetch(:moneda, 'MXN')
|
99
|
+
child_pago_relacionado['MetodoDePagoDR'] = 'PPD'
|
100
|
+
child_pago_relacionado['NumParcialidad'] = (index + 1).to_s
|
101
|
+
|
102
|
+
child_pago_relacionado['ImpSaldoAnt'] = (saldo_anterior).round(2).to_s
|
103
|
+
child_pago_relacionado['ImpPagado'] = monto.round(2).to_s
|
104
|
+
child_pago_relacionado['ImpSaldoInsoluto'] = (saldo_anterior - monto).round(2).to_s
|
105
|
+
saldo_anterior -= monto
|
106
|
+
|
107
|
+
child_pago.add_child(child_pago_relacionado)
|
100
108
|
end
|
101
109
|
|
102
110
|
# puts '---------------- Xml resultante comprobante de pago -----------------------'
|
@@ -122,7 +130,7 @@ module SwFac
|
|
122
130
|
# puts '------ comprobante de pago antes de timbre -------'
|
123
131
|
# puts xml.to_xml
|
124
132
|
|
125
|
-
|
133
|
+
base64_xml = Base64.encode64(xml.to_xml)
|
126
134
|
request = Net::HTTP::Post.new(uri)
|
127
135
|
request.basic_auth(token, "")
|
128
136
|
request.content_type = "application/json"
|
@@ -147,7 +155,7 @@ module SwFac
|
|
147
155
|
})
|
148
156
|
|
149
157
|
req_options = {
|
150
|
-
|
158
|
+
use_ssl: false,
|
151
159
|
}
|
152
160
|
|
153
161
|
json_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
@@ -341,6 +349,7 @@ module SwFac
|
|
341
349
|
# params = {
|
342
350
|
# uuid: '',
|
343
351
|
# rfc_emisor: '',
|
352
|
+
# motivo: '02',
|
344
353
|
# key_password: '', # optional
|
345
354
|
# cer_cadena: '', # optional
|
346
355
|
# key_pem: '' # optional
|
@@ -360,6 +369,7 @@ module SwFac
|
|
360
369
|
'uuid': params[:uuid],
|
361
370
|
"password": params.fetch(:key_password, @key_pass),
|
362
371
|
"rfc": params.fetch(:rfc_emisor, @rfc),
|
372
|
+
"motivo": '02',
|
363
373
|
"b64Cer": params.fetch(:cer_cadena, @cadena),
|
364
374
|
"b64Key": params.fetch(:key_pem, @pem_cadena)
|
365
375
|
})
|
@@ -402,6 +412,46 @@ module SwFac
|
|
402
412
|
|
403
413
|
end
|
404
414
|
|
415
|
+
def timbra_v4(params={})
|
416
|
+
puts "---- SwFacturacion:facturacion:timbra_v4"
|
417
|
+
|
418
|
+
### sample params
|
419
|
+
#
|
420
|
+
# params = {
|
421
|
+
# moneda: 'MXN',
|
422
|
+
# series: 'FA',
|
423
|
+
# folio: '003',
|
424
|
+
# forma_pago: '',
|
425
|
+
# metodo_pago: 'PUE',
|
426
|
+
# cp: '47180',
|
427
|
+
# receptor_razon: 'Car zone',
|
428
|
+
# receptor_rfc: '',
|
429
|
+
# receptor_regimen: '',
|
430
|
+
# uso_cfdi: 'G03',
|
431
|
+
# time: "%Y-%m-%dT%H:%M:%S",
|
432
|
+
# line_items: [
|
433
|
+
# {
|
434
|
+
# clave_prod_serv: '78181500',
|
435
|
+
# clave_unidad: 'E48',
|
436
|
+
# unidad: 'Servicio',
|
437
|
+
# sku: 'serv001',
|
438
|
+
# cantidad: 1,
|
439
|
+
# descripcion: 'Servicio mano de obra',
|
440
|
+
# valor_unitario: 100.00,
|
441
|
+
# descuento: 0.00,
|
442
|
+
# tax_included: true,
|
443
|
+
# retencion_iva: 0, 6, 16
|
444
|
+
# # Optional parameters
|
445
|
+
# },
|
446
|
+
# ]
|
447
|
+
|
448
|
+
# }
|
449
|
+
|
450
|
+
uri = @production ? URI("#{SwFac::UrlProduction}cfdi33/stamp/customv1/b64") : URI("#{SwFac::UrlDev}cfdi33/stamp/customv1/b64")
|
451
|
+
token = @production ? @production_token : @dev_token
|
452
|
+
time = params.fetch(:time, (Time.now).strftime("%Y-%m-%dT%H:%M:%S"))
|
453
|
+
end
|
454
|
+
|
405
455
|
def timbra_doc(params={})
|
406
456
|
### sample params
|
407
457
|
#
|
@@ -644,8 +694,8 @@ module SwFac
|
|
644
694
|
id = SecureRandom.hex
|
645
695
|
|
646
696
|
FileUtils.mkdir_p(path) unless File.exist?(path)
|
647
|
-
|
648
|
-
|
697
|
+
File.write("#{path}/tmp_#{id}.xml", xml.to_xml)
|
698
|
+
xml_path = "#{path}/tmp_#{id}.xml"
|
649
699
|
cadena_path = File.join(File.dirname(__FILE__), *%w[.. cadena cadena33.xslt])
|
650
700
|
|
651
701
|
# puts File.read(cadena_path)
|
@@ -734,6 +784,207 @@ module SwFac
|
|
734
784
|
|
735
785
|
|
736
786
|
|
787
|
+
end
|
788
|
+
|
789
|
+
def timbra_doc_cero(params={})
|
790
|
+
puts "---- SwFacturacion:facturacion:timbra_doc_cero"
|
791
|
+
# params = {
|
792
|
+
# moneda: 'MXN',
|
793
|
+
# series: 'FA',
|
794
|
+
# folio: '003',
|
795
|
+
# forma_pago: '',
|
796
|
+
# metodo_pago: 'PUE',
|
797
|
+
# cp: '47180',
|
798
|
+
# receptor_razon: 'Car zone',
|
799
|
+
# receptor_rfc: '',
|
800
|
+
# uso_cfdi: 'G03',
|
801
|
+
# time: "%Y-%m-%dT%H:%M:%S",
|
802
|
+
# line_items: [
|
803
|
+
# {
|
804
|
+
# clave_prod_serv: '78181500',
|
805
|
+
# clave_unidad: 'E48',
|
806
|
+
# unidad: 'Servicio',
|
807
|
+
# sku: 'serv001',
|
808
|
+
# cantidad: 1,
|
809
|
+
# descripcion: 'Servicio mano de obra',
|
810
|
+
# valor_unitario: 100.00,
|
811
|
+
# # Optional parameters
|
812
|
+
# },
|
813
|
+
# ]
|
814
|
+
|
815
|
+
# }
|
816
|
+
|
817
|
+
uri = @production ? URI("#{SwFac::UrlProduction}cfdi33/stamp/customv1/b64") : URI("#{SwFac::UrlDev}cfdi33/stamp/customv1/b64")
|
818
|
+
token = @production ? @production_token : @dev_token
|
819
|
+
time = params.fetch(:time, (Time.now).strftime("%Y-%m-%dT%H:%M:%S"))
|
820
|
+
|
821
|
+
xml = Nokogiri::XML(SwFac::DocBaseCero)
|
822
|
+
comprobante = xml.at_xpath("//cfdi:Comprobante")
|
823
|
+
comprobante['TipoCambio'] = '1'
|
824
|
+
comprobante['TipoDeComprobante'] = 'I'
|
825
|
+
comprobante['Serie'] = params.fetch(:series, 'FA').to_s
|
826
|
+
comprobante['Folio'] = params.fetch(:folio, '1').to_s
|
827
|
+
comprobante['Fecha'] = time.to_s
|
828
|
+
comprobante['FormaPago'] = params.fetch(:forma_pago, '01')
|
829
|
+
comprobante['MetodoPago'] = params.fetch(:metodo_pago, 'PUE')
|
830
|
+
comprobante['LugarExpedicion'] = params.fetch(:cp, '55555')
|
831
|
+
comprobante['NoCertificado'] = @serial
|
832
|
+
comprobante['Certificado'] = @cadena
|
833
|
+
|
834
|
+
emisor = xml.at_xpath("//cfdi:Emisor")
|
835
|
+
emisor['Nombre'] = @razon
|
836
|
+
emisor['RegimenFiscal'] = @regimen_fiscal
|
837
|
+
emisor['Rfc'] = @rfc
|
838
|
+
|
839
|
+
receptor = xml.at_xpath("//cfdi:Receptor")
|
840
|
+
receptor['Nombre'] = params.fetch(:receptor_razon, '')
|
841
|
+
receptor['Rfc'] = params.fetch(:receptor_rfc, 'XAXX010101000')
|
842
|
+
receptor['UsoCFDI'] = params.fetch(:uso_cfdi, 'G03')
|
843
|
+
|
844
|
+
|
845
|
+
# impuestos = xml.at_xpath("//cfdi:Impuestos")
|
846
|
+
# traslados = Nokogiri::XML::Node.new "cfdi:Traslados", xml
|
847
|
+
|
848
|
+
|
849
|
+
puts '--- sw_fac time -----'
|
850
|
+
puts time
|
851
|
+
puts '--------'
|
852
|
+
|
853
|
+
conceptos = xml.at_xpath("//cfdi:Conceptos")
|
854
|
+
|
855
|
+
line_items = params[:line_items]
|
856
|
+
|
857
|
+
suma_total = 0.00
|
858
|
+
|
859
|
+
line_items.each do |line|
|
860
|
+
|
861
|
+
valor_unitario = line[:valor_unitario].to_f
|
862
|
+
cantidad = line[:cantidad].to_f
|
863
|
+
total_line = cantidad * valor_unitario
|
864
|
+
|
865
|
+
suma_total += total_line
|
866
|
+
|
867
|
+
## Creando y poblando CFDI:CONCEPTO
|
868
|
+
child_concepto = Nokogiri::XML::Node.new "cfdi:Concepto", xml
|
869
|
+
child_concepto['ClaveProdServ'] = line[:clave_prod_serv].to_s
|
870
|
+
child_concepto['NoIdentificacion'] = line[:sku].to_s
|
871
|
+
child_concepto['ClaveUnidad'] = line[:clave_unidad].to_s
|
872
|
+
child_concepto['Unidad'] = line[:unidad].to_s
|
873
|
+
child_concepto['Descripcion'] = line[:descripcion].to_s
|
874
|
+
child_concepto['Cantidad'] = cantidad.to_s
|
875
|
+
child_concepto['ValorUnitario'] = valor_unitario.round(4).to_s
|
876
|
+
child_concepto['Importe'] = total_line.round(4).to_s
|
877
|
+
|
878
|
+
|
879
|
+
# Joining all up
|
880
|
+
conceptos.add_child(child_concepto)
|
881
|
+
|
882
|
+
|
883
|
+
end
|
884
|
+
|
885
|
+
puts '------ Totales -----'
|
886
|
+
puts "Subtotal = #{suma_total}"
|
887
|
+
puts "Total = #{suma_total}"
|
888
|
+
|
889
|
+
comprobante['Moneda'] = params.fetch(:moneda, 'MXN')
|
890
|
+
comprobante['SubTotal'] = suma_total.round(2).to_s
|
891
|
+
comprobante['Total'] = suma_total.round(2).to_s
|
892
|
+
|
893
|
+
|
894
|
+
|
895
|
+
path = File.join(File.dirname(__FILE__), *%w[.. tmp])
|
896
|
+
id = SecureRandom.hex
|
897
|
+
|
898
|
+
FileUtils.mkdir_p(path) unless File.exist?(path)
|
899
|
+
File.write("#{path}/tmp_#{id}.xml", xml.to_xml)
|
900
|
+
xml_path = "#{path}/tmp_#{id}.xml"
|
901
|
+
cadena_path = File.join(File.dirname(__FILE__), *%w[.. cadena cadena33.xslt])
|
902
|
+
|
903
|
+
# puts File.read(cadena_path)
|
904
|
+
File.write("#{path}/pem_#{id}.pem", @pem)
|
905
|
+
key_pem_url = "#{path}/pem_#{id}.pem"
|
906
|
+
sello = %x[xsltproc #{cadena_path} #{xml_path} | openssl dgst -sha256 -sign #{key_pem_url} | openssl enc -base64 -A]
|
907
|
+
comprobante['Sello'] = sello
|
908
|
+
|
909
|
+
File.delete("#{xml_path}")
|
910
|
+
File.delete("#{key_pem_url}")
|
911
|
+
|
912
|
+
puts '---- SW GEM comprobante sin timbrar ------'
|
913
|
+
puts xml.to_xml
|
914
|
+
puts '-------------------------'
|
915
|
+
|
916
|
+
base64_xml = Base64.encode64(xml.to_xml)
|
917
|
+
request = Net::HTTP::Post.new(uri)
|
918
|
+
request.basic_auth(token, "")
|
919
|
+
request.content_type = "application/json"
|
920
|
+
request["cache-control"] = 'no-cache'
|
921
|
+
request.body = JSON.dump({
|
922
|
+
"credentials" => {
|
923
|
+
"id" => params.fetch(:folio).to_s,
|
924
|
+
"token" => token
|
925
|
+
},
|
926
|
+
"issuer" => {
|
927
|
+
"rfc" => emisor['Rfc']
|
928
|
+
},
|
929
|
+
"document" => {
|
930
|
+
"ref-id": params.fetch(:folio).to_s,
|
931
|
+
"certificate-number": comprobante['NoCertificado'],
|
932
|
+
"section": "all",
|
933
|
+
"format": "xml",
|
934
|
+
"template": "letter",
|
935
|
+
"type": "application/xml",
|
936
|
+
"content": base64_xml
|
937
|
+
}
|
938
|
+
})
|
939
|
+
|
940
|
+
req_options = {
|
941
|
+
use_ssl: false,
|
942
|
+
}
|
943
|
+
|
944
|
+
json_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
945
|
+
http.request(request)
|
946
|
+
end
|
947
|
+
|
948
|
+
puts "-- SW API reponse..."
|
949
|
+
puts "-- Response code: #{json_response.code} --"
|
950
|
+
puts "-- Response body: #{json_response.body} --"
|
951
|
+
puts "-- Response message: #{json_response.message} --"
|
952
|
+
|
953
|
+
response = JSON.parse(json_response.body)
|
954
|
+
|
955
|
+
if json_response.code == '200'
|
956
|
+
decoded_xml = Nokogiri::XML(Base64.decode64(response['content']))
|
957
|
+
timbre = decoded_xml.at_xpath("//cfdi:Complemento").children.first
|
958
|
+
|
959
|
+
response = {
|
960
|
+
status: 200,
|
961
|
+
message_error: '',
|
962
|
+
xml: decoded_xml.to_xml,
|
963
|
+
uuid: response['uuid'],
|
964
|
+
fecha_timbrado: timbre['FechaTimbrado'],
|
965
|
+
sello_cfd: timbre['SelloCFD'],
|
966
|
+
sello_sat: timbre['SelloSAT'],
|
967
|
+
no_certificado_sat: timbre['NoCertificadoSAT'],
|
968
|
+
}
|
969
|
+
|
970
|
+
return response
|
971
|
+
else
|
972
|
+
|
973
|
+
response ={
|
974
|
+
status: json_response.code,
|
975
|
+
message_error: "Error message: #{json_response.message}, #{response['message']} #{response['error_details']}",
|
976
|
+
xml: '',
|
977
|
+
uuid: '',
|
978
|
+
fecha_timbrado: '',
|
979
|
+
sello_cfd: '',
|
980
|
+
sello_sat: '',
|
981
|
+
no_certificado_sat: '',
|
982
|
+
}
|
983
|
+
|
984
|
+
return response
|
985
|
+
end
|
986
|
+
|
987
|
+
|
737
988
|
end
|
738
989
|
|
739
990
|
|
data/lib/sw_fac/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sw_fac
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.63
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Angel Padilla
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
requirements: []
|
132
|
-
rubygems_version: 3.0.
|
132
|
+
rubygems_version: 3.0.1
|
133
133
|
signing_key:
|
134
134
|
specification_version: 4
|
135
135
|
summary: Gem used to fetch the Smarter Web API
|