facturama-ruby-sdk 0.0.3

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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/lib/facturama/facturama_api_multi.rb +29 -0
  3. data/lib/facturama/facturama_api_web.rb +47 -0
  4. data/lib/facturama/models/address.rb +17 -0
  5. data/lib/facturama/models/branch_office.rb +16 -0
  6. data/lib/facturama/models/cfdi.rb +77 -0
  7. data/lib/facturama/models/cfdi_relation.rb +11 -0
  8. data/lib/facturama/models/cfdi_relations.rb +13 -0
  9. data/lib/facturama/models/client.rb +19 -0
  10. data/lib/facturama/models/complement.rb +9 -0
  11. data/lib/facturama/models/connection_info.rb +21 -0
  12. data/lib/facturama/models/csd.rb +14 -0
  13. data/lib/facturama/models/exception/facturama_exception.rb +13 -0
  14. data/lib/facturama/models/exception/model_exception.rb +8 -0
  15. data/lib/facturama/models/globalInformation.rb +15 -0
  16. data/lib/facturama/models/image.rb +12 -0
  17. data/lib/facturama/models/item.rb +29 -0
  18. data/lib/facturama/models/model.rb +68 -0
  19. data/lib/facturama/models/product.rb +25 -0
  20. data/lib/facturama/models/product_tax.rb +14 -0
  21. data/lib/facturama/models/receiver.rb +18 -0
  22. data/lib/facturama/models/serie.rb +15 -0
  23. data/lib/facturama/models/tax.rb +15 -0
  24. data/lib/facturama/models/tax_entity.rb +22 -0
  25. data/lib/facturama/models/tax_stamp.rb +13 -0
  26. data/lib/facturama/models/thirdPartyAccount.rb +14 -0
  27. data/lib/facturama/services/branch_office_service.rb +13 -0
  28. data/lib/facturama/services/catalog_service.rb +39 -0
  29. data/lib/facturama/services/cfdi_multi_service.rb +130 -0
  30. data/lib/facturama/services/cfdi_service.rb +137 -0
  31. data/lib/facturama/services/client_service.rb +13 -0
  32. data/lib/facturama/services/crud_service.rb +33 -0
  33. data/lib/facturama/services/csd_service.rb +13 -0
  34. data/lib/facturama/services/http_service.rb +115 -0
  35. data/lib/facturama/services/product_service.rb +13 -0
  36. data/lib/facturama/version.rb +5 -0
  37. data/lib/facturama.rb +42 -0
  38. data/lib/samples/sample_api.rb +11 -0
  39. data/lib/samples/sample_api_multi.rb +367 -0
  40. data/lib/samples/sample_api_web.rb +458 -0
  41. metadata +95 -0
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'crud_service'
4
+ require 'base64'
5
+
6
+ module Facturama
7
+ module Services
8
+ class CfdiMultiService < CrudService
9
+ def initialize(connection_info)
10
+ super(connection_info, '')
11
+ end
12
+
13
+ # ------------------------ CRUD ------------------------
14
+
15
+ # CFDI 3.3
16
+ def create(model)
17
+ post(model, 'api-lite/2/cfdis')
18
+ end
19
+
20
+ # CFDI 4.0
21
+ def create3(model)
22
+ post(model, 'api-lite/3/cfdis')
23
+ end
24
+
25
+ def remove(id, motive, uuidReplacement)
26
+ motive = '02' if motive.nil? && motive != ''
27
+ uuidReplacement = '' if uuidReplacement.nil? && uuidReplacement != ''
28
+
29
+ raise(FacturamaException('El Id del cfdi a eliminar es obligatorio')) unless !id.nil? && id != ''
30
+
31
+ delete("api-lite/cfdis/#{id}?motive=#{motive}&uuidReplacement=#{uuidReplacement}")
32
+ end
33
+
34
+ def retrieve(id)
35
+ get("api-lite/cfdis/#{id}")
36
+ end
37
+
38
+ # ------------------------ DESCARGA DE ARCHIVOS (PDF, XML, HTML) ------------------------
39
+
40
+ # Obtiene un archivo referente a un CFDI del tipo "Issued"
41
+ # @param id Identificador del CFDI
42
+ # @param format Formato deseado ( pdf | html | xml )
43
+ # @param type Tipo de comprobante ( payroll | received | issued )
44
+ # @return Archivo en cuestion
45
+ def get_file(id, format, type)
46
+ resource = "cfdi/#{format}/#{type}/#{id}"
47
+ get(resource)
48
+ end
49
+
50
+ # Decodifica y guarda un archivo base64 en una ruta
51
+ def save_file(file_path, file_content_base64)
52
+ file_content_decoded = Base64.decode64(file_content_base64)
53
+ File.open(file_path, 'wb') do |f|
54
+ f.write(file_content_decoded)
55
+ end
56
+ end
57
+
58
+ def save_pdf(file_path, id, type = Facturama::InvoiceType::ISSUED_LITE)
59
+ file_content = get_file(id, Facturama::FileFormat::PDF, type)
60
+ save_file(file_path, file_content['Content'])
61
+ end
62
+
63
+ def save_xml(file_path, id, type = Facturama::InvoiceType::ISSUED_LITE)
64
+ file_content = get_file(id, Facturama::FileFormat::XML, type)
65
+ save_file(file_path, file_content['Content'])
66
+ end
67
+
68
+ def save_html(file_path, id, type = Facturama::InvoiceType::ISSUED_LITE)
69
+ file_content = get_file(id, Facturama::FileFormat::HTML, type)
70
+ save_file(file_path, file_content['Content'])
71
+ end
72
+
73
+ # ------------------------ LISTADO DE CFDIS ------------------------
74
+
75
+ # Listado de Cfdi filtrando por palabra clave
76
+ def list_by_keyword(keyword,
77
+ status = Facturama::CfdiStatus::ACTIVE)
78
+
79
+ resource = "api-lite/cfdis?status=#{status}&keyword=#{keyword}"
80
+ get(resource)
81
+ end
82
+
83
+ # Listado de Cfdi filtrando por palabra RFC
84
+ def list_by_rfc(rfc,
85
+ status = Facturama::CfdiStatus::ACTIVE,
86
+ _type = Facturama::InvoiceType::ISSUED)
87
+
88
+ resource = "api-lite/cfdis?status=#{status}&rfc=#{rfc}"
89
+ get(resource)
90
+ end
91
+
92
+ # Listado con todas las opciones posibles
93
+ def list(folio_start = -1, folio_end = -1,
94
+ rfc = nil, tax_entity_name = nil,
95
+ date_start = nil, date_end = nil,
96
+ id_branch = nil, serie = nil,
97
+ status = Facturama::CfdiStatus::ACTIVE,
98
+ type = Facturama::InvoiceType::ISSUED)
99
+
100
+ resource = "api-lite/cfdis?type=#{type}&status=#{status}"
101
+
102
+ resource += "&folioStart=#{folio_start}" if folio_start > -1
103
+
104
+ resource += "&folioEnd=#{folio_end}" if folio_end > -1
105
+
106
+ resource += "&rfc=#{rfc}" unless rfc.nil?
107
+
108
+ resource += "&taxEntityName=#{tax_entity_name}" unless tax_entity_name.nil?
109
+
110
+ resource += "&dateStart=#{date_start}" unless date_start.nil?
111
+
112
+ resource += "&dateEnd=#{date_end}" unless date_end.nil?
113
+
114
+ resource += "&idBranch=#{id_branch}" unless id_branch.nil?
115
+
116
+ resource += "&serie=#{serie}" unless serie.nil?
117
+
118
+ get(resource)
119
+ end
120
+
121
+ # ------------------------ ENVIO POR CORREO ------------------------
122
+
123
+ # Envía el CFDI por correo, con el asunto especificado
124
+ def send_by_mail(id, email, subject, type = Facturama::InvoiceType::ISSUED_LITE)
125
+ response = post(nil, "cfdi?cfdiType=#{type}&cfdiId=#{id}&email=#{email}&subject=#{subject}")
126
+ !!response['success']
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'crud_service'
4
+ require 'base64'
5
+
6
+ module Facturama
7
+ module Services
8
+ class CfdiService < CrudService
9
+ def initialize(connection_info)
10
+ super(connection_info, '')
11
+ end
12
+
13
+ # ------------------------ CRUD ------------------------
14
+
15
+ # CFDI 3.3
16
+ def create(model)
17
+ post(model, '2/cfdis')
18
+ end
19
+
20
+ # CFDI 4.0
21
+ def create3(model)
22
+ post(model, '3/cfdis')
23
+ end
24
+
25
+ def remove(id, type, motive, uuidReplacement)
26
+ motive = '02' if motive.nil? && motive != ''
27
+ uuidReplacement = '' if uuidReplacement.nil? && uuidReplacement != ''
28
+
29
+ raise(FacturamaException('El Id del cfdi a eliminar es obligatorio')) unless !id.nil? && id != ''
30
+
31
+ delete("cfdi/#{id}?type=#{type}&motive=#{motive}&uuidReplacement=#{uuidReplacement}")
32
+ end
33
+
34
+ def retrieve(id, type = nil)
35
+ str_type = if type.nil?
36
+ 'Issued'
37
+ else
38
+ type
39
+ end
40
+
41
+ get("cfdi/#{id}?type=#{str_type}")
42
+ end
43
+
44
+ # ------------------------ DESCARGA DE ARCHIVOS (PDF, XML, HTML) ------------------------
45
+
46
+ # Obtiene un archivo referente a un CFDI del tipo "Issued"
47
+ # @param id Identificador del CFDI
48
+ # @param format Formato deseado ( pdf | html | xml )
49
+ # @param type Tipo de comprobante ( payroll | received | issued )
50
+ # @return Archivo en cuestion
51
+ def get_file(id, format, type)
52
+ resource = "api/cfdi/#{format}/#{type}/#{id}"
53
+ get(resource)
54
+ end
55
+
56
+ # Decodifica y guarda un archivo base64 en una ruta
57
+ def save_file(file_path, file_content_base64)
58
+ file_content_decoded = Base64.decode64(file_content_base64)
59
+ File.open(file_path, 'wb') do |f|
60
+ f.write(file_content_decoded)
61
+ end
62
+ end
63
+
64
+ def save_pdf(file_path, id, type = Facturama::InvoiceType::ISSUED)
65
+ file_content = get_file(id, Facturama::FileFormat::PDF, type)
66
+ save_file(file_path, file_content['Content'])
67
+ end
68
+
69
+ def save_xml(file_path, id, type = Facturama::InvoiceType::ISSUED)
70
+ file_content = get_file(id, Facturama::FileFormat::XML, type)
71
+ save_file(file_path, file_content['Content'])
72
+ end
73
+
74
+ def save_html(file_path, id, type = Facturama::InvoiceType::ISSUED)
75
+ file_content = get_file(id, Facturama::FileFormat::HTML, type)
76
+ save_file(file_path, file_content['Content'])
77
+ end
78
+
79
+ # ------------------------ LISTADO DE CFDIS ------------------------
80
+
81
+ # Listado de Cfdi filtrando por palabra clave
82
+ def list_by_keyword(keyword,
83
+ status = Facturama::CfdiStatus::ACTIVE,
84
+ type = Facturama::InvoiceType::ISSUED)
85
+
86
+ resource = "cfdi?type=#{type}&status=#{status}&keyword=#{keyword}"
87
+ get(resource)
88
+ end
89
+
90
+ # Listado de Cfdi filtrando por palabra RFC
91
+ def list_by_rfc(rfc,
92
+ status = Facturama::CfdiStatus::ACTIVE,
93
+ type = Facturama::InvoiceType::ISSUED)
94
+
95
+ resource = "cfdi?type=#{type}&status=#{status}&rfc=#{rfc}"
96
+ get(resource)
97
+ end
98
+
99
+ # Listado con todas las opciones posibles
100
+ def list(folio_start = -1, folio_end = -1,
101
+ rfc = nil, tax_entity_name = nil,
102
+ date_start = nil, date_end = nil,
103
+ id_branch = nil, serie = nil,
104
+ status = Facturama::CfdiStatus::ACTIVE,
105
+ type = Facturama::InvoiceType::ISSUED)
106
+
107
+ resource = "cfdi?type=#{type}&status=#{status}"
108
+
109
+ resource += "&folioStart=#{folio_start}" if folio_start > -1
110
+
111
+ resource += "&folioEnd=#{folio_end}" if folio_end > -1
112
+
113
+ resource += "&rfc=#{rfc}" unless rfc.nil?
114
+
115
+ resource += "&taxEntityName=#{tax_entity_name}" unless tax_entity_name.nil?
116
+
117
+ resource += "&dateStart=#{date_start}" unless date_start.nil?
118
+
119
+ resource += "&dateEnd=#{date_end}" unless date_end.nil?
120
+
121
+ resource += "&idBranch=#{id_branch}" unless id_branch.nil?
122
+
123
+ resource += "&serie=#{serie}" unless serie.nil?
124
+
125
+ get(resource)
126
+ end
127
+
128
+ # ------------------------ ENVIO POR CORREO ------------------------
129
+
130
+ # Envía el CFDI por correo, con el asunto especificado
131
+ def send_by_mail(id, email, subject, type = Facturama::InvoiceType::ISSUED)
132
+ response = post(nil, "cfdi?cfdiType=#{type}&cfdiId=#{id}&email=#{email}&subject=#{subject}")
133
+ !!response['success']
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'crud_service'
4
+
5
+ module Facturama
6
+ module Services
7
+ class ClientService < CrudService
8
+ def initialize(connection_info)
9
+ super(connection_info, 'client')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'http_service'
4
+
5
+ module Facturama
6
+ module Services
7
+ class CrudService < HttpService
8
+ def retrieve(message)
9
+ HttpService.instance_method(:get).bind(self).call(message)
10
+ end
11
+
12
+ def list
13
+ HttpService.instance_method(:get).bind(self).call('')
14
+ end
15
+
16
+ def create(message, url = '')
17
+ HttpService.instance_method(:post).bind(self).call(message, url)
18
+ end
19
+
20
+ def create3(message, url = '')
21
+ HttpService.instance_method(:post).bind(self).call(message, url)
22
+ end
23
+
24
+ def remove(message)
25
+ HttpService.instance_method(:delete).bind(self).call(message)
26
+ end
27
+
28
+ def update(message, url = '')
29
+ HttpService.instance_method(:put).bind(self).call(message, url)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'crud_service'
4
+
5
+ module Facturama
6
+ module Services
7
+ class CsdService < CrudService
8
+ def initialize(connection_info)
9
+ super(connection_info, 'api-lite/csds')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../models/exception/facturama_exception'
4
+ require_relative '../models/connection_info'
5
+
6
+ module Facturama
7
+ module Services
8
+ class HttpService
9
+ def initialize(connection_info, uri_resource)
10
+ @connection_info = connection_info
11
+ @uri_resource = uri_resource
12
+ end
13
+
14
+ def get(args = '')
15
+ res = RestClient::Request.new(
16
+ method: :get,
17
+ url: url(args),
18
+ user: @connection_info.facturama_user,
19
+ password: @connection_info.facturama_password,
20
+ headers: { accept: :json,
21
+ content_type: :json,
22
+ user_agent: '' }
23
+ )
24
+
25
+ executor(res)
26
+ end
27
+
28
+ def post(message, args = '')
29
+ json = message.to_json
30
+
31
+ res = RestClient::Request.new(
32
+ method: :post,
33
+ url: url(args),
34
+ user: @connection_info.facturama_user,
35
+ password: @connection_info.facturama_password,
36
+ payload: json,
37
+ headers: { content_type: :json }
38
+ )
39
+
40
+ executor(res)
41
+ end
42
+
43
+ def put(message, args = '')
44
+ json = message.to_json
45
+
46
+ res = RestClient::Request.new(
47
+ method: :put,
48
+ url: url(args),
49
+ user: @connection_info.facturama_user,
50
+ password: @connection_info.facturama_password,
51
+ payload: json,
52
+ headers: { accept: :json,
53
+ content_type: :json }
54
+ )
55
+
56
+ executor(res)
57
+ end
58
+
59
+ def delete(args = '')
60
+ res = RestClient::Request.new(
61
+ method: :delete,
62
+ url: url(args),
63
+ user: @connection_info.facturama_user,
64
+ password: @connection_info.facturama_password,
65
+ headers: { accept: :json,
66
+ content_type: :json }
67
+ )
68
+
69
+ executor(res)
70
+ end
71
+
72
+ private
73
+
74
+ def url(args = '')
75
+ slash = ''
76
+ args = args.to_s
77
+
78
+ if args.length.positive?
79
+ slash = args =~ /^\?/ ? '' : '/'
80
+ end
81
+
82
+ @uri_resource = "/#{@uri_resource}" if @uri_resource.length.positive?
83
+
84
+ @connection_info.uri_base + @uri_resource + slash + args
85
+ end
86
+
87
+ # Executa la peticion y procesa la respuesta decodificando el JSON a un Hash y
88
+ # Conviriendo los errores de la API en FacturamaExceptions
89
+ def executor(request)
90
+ response = request.execute
91
+
92
+ JSON[response] if response.code != 204 && response.body != '' # 204 = sin contenido
93
+
94
+ # exceptions
95
+ rescue Exception => e
96
+ case e.class.name
97
+ when 'RestClient::NotFound'
98
+ raise FacturamaException, '404 NotFound: Elemento no encontrado'
99
+ when 'RestClient::BadRequest'
100
+ json_response = JSON[e.response]
101
+ model_state = json_response['ModelState']
102
+ unless model_state.nil?
103
+ model_state = json_response['ModelState'].map { |k, v| [k.to_s, v] }
104
+ fact_exception = FacturamaException.new(json_response['Message'])
105
+ end
106
+
107
+ fact_exception = FacturamaException.new(json_response['Message'], model_state)
108
+ raise(fact_exception)
109
+ else
110
+ raise StandardError, e.response
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'crud_service'
4
+
5
+ module Facturama
6
+ module Services
7
+ class ProductService < CrudService
8
+ def initialize(connection_info)
9
+ super(connection_info, 'product')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facturama
4
+ VERSION = '0.0.3'
5
+ end
data/lib/facturama.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Conectividad
4
+ # require 'rest-client'
5
+ # require 'json'
6
+
7
+ module Facturama
8
+ # MODELOS
9
+ require_relative 'facturama/version'
10
+ require_relative 'facturama/models/model'
11
+ require_relative 'facturama/models/product_tax'
12
+ require_relative 'facturama/models/product'
13
+ require_relative 'facturama/models/address'
14
+ require_relative 'facturama/models/client'
15
+ require_relative 'facturama/models/cfdi_relation'
16
+ require_relative 'facturama/models/cfdi_relations'
17
+ require_relative 'facturama/models/cfdi'
18
+ require_relative 'facturama/models/receiver'
19
+ require_relative 'facturama/models/tax'
20
+ require_relative 'facturama/models/item'
21
+ require_relative 'facturama/models/branch_office'
22
+ require_relative 'facturama/models/csd'
23
+ require_relative 'facturama/models/serie'
24
+ require_relative 'facturama/models/image'
25
+ require_relative 'facturama/models/complement'
26
+ require_relative 'facturama/models/tax_stamp'
27
+ require_relative 'facturama/models/tax_entity'
28
+
29
+ # SERVICIOS
30
+ require_relative 'facturama/services/http_service'
31
+ require_relative 'facturama/services/crud_service'
32
+ require_relative 'facturama/services/client_service'
33
+ require_relative 'facturama/services/product_service'
34
+ require_relative 'facturama/services/catalog_service'
35
+ require_relative 'facturama/services/branch_office_service'
36
+ require_relative 'facturama/services/cfdi_service'
37
+ require_relative 'facturama/services/csd_service'
38
+ require_relative 'facturama/services/cfdi_multi_service'
39
+
40
+ require_relative 'facturama/facturama_api_web'
41
+ require_relative 'facturama/facturama_api_multi'
42
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facturama
4
+ module Samples
5
+ class SampleApi
6
+ def run
7
+ rasie 'Este método debe ser sobrecargado, colocando las pruebas adecuadas, segun el tipo de API (Web, Multiemisor)'
8
+ end
9
+ end
10
+ end
11
+ end