sw_fac 0.3.58.1 → 0.3.63

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5eae8e8ff634c17390c533c6b652bdc12c7ac27be0ee4436111ba340d2ff1cad
4
- data.tar.gz: 4b39fc66e28f553a5bd85911fdb6cf29a631d115fa690b946b62ff0ddf6fd558
3
+ metadata.gz: ff59c51cb10373fbc6e32713380a3f4b375e90f962086d71254ca11075e39ada
4
+ data.tar.gz: 9add1352a09c499c0201b83d9bd73853494d34e1dab295e8bcd46ed4a205155b
5
5
  SHA512:
6
- metadata.gz: 3933c3d8948006205e8373caccb6797083e12127b8cc6125ba692b40af58d65302c89df7fec1c0293e5c02f7935a6a7809977346e13f5099a702fdc3f3ede89d
7
- data.tar.gz: d410c5841b3cd3deec5ca6cae62bff2c847db723c8d5f88e489736fd4b664b742b0fa1348570a3832f8e5647891f9fa7530699108aa7581df16541541b3134eb
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
 
@@ -12,7 +12,8 @@ module SwFac
12
12
  # receptor_rfc: 'XAXX010101000',
13
13
  # forma_pago: '01',
14
14
  # total: 100.00,
15
- # time: '',
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
- time = params.fetch(:time, (Time.now).strftime("%Y-%m-%dT%H:%M:%S"))
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
- base_doc.delete!("\t")
68
+ base_doc.delete!("\t")
61
69
 
62
- xml = Nokogiri::XML(base_doc)
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'] = time
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'] = time
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
- monto = line[:monto].to_f
88
- child_pago_relacionado = Nokogiri::XML::Node.new "pago10:DoctoRelacionado", xml
89
- child_pago_relacionado['IdDocumento'] = params[:uuid]
90
- child_pago_relacionado['MonedaDR'] = line.fetch(:moneda, 'MXN')
91
- child_pago_relacionado['MetodoDePagoDR'] = 'PPD'
92
- child_pago_relacionado['NumParcialidad'] = (index + 1).to_s
93
-
94
- child_pago_relacionado['ImpSaldoAnt'] = (saldo_anterior).round(2).to_s
95
- child_pago_relacionado['ImpPagado'] = monto.round(2).to_s
96
- child_pago_relacionado['ImpSaldoInsoluto'] = (saldo_anterior - monto).round(2).to_s
97
- saldo_anterior -= monto
98
-
99
- child_pago.add_child(child_pago_relacionado)
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
- base64_xml = Base64.encode64(xml.to_xml)
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
- use_ssl: false,
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
- File.write("#{path}/tmp_#{id}.xml", xml.to_xml)
648
- xml_path = "#{path}/tmp_#{id}.xml"
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
 
@@ -1,3 +1,3 @@
1
1
  module SwFac
2
- VERSION = "0.3.58.1"
2
+ VERSION = "0.3.63"
3
3
  end
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.58.1
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: 2021-10-26 00:00:00.000000000 Z
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.3
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