facturama 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/lib/facturama.rb +56 -0
  3. data/lib/facturama/facturama_api_multi.rb +37 -0
  4. data/lib/facturama/facturama_api_web.rb +55 -0
  5. data/lib/facturama/models/address.rb +16 -0
  6. data/lib/facturama/models/branch_office.rb +14 -0
  7. data/lib/facturama/models/cfdi.rb +80 -0
  8. data/lib/facturama/models/cfdi_relation.rb +10 -0
  9. data/lib/facturama/models/cfdi_relations.rb +12 -0
  10. data/lib/facturama/models/client.rb +19 -0
  11. data/lib/facturama/models/complement.rb +8 -0
  12. data/lib/facturama/models/connection_info.rb +36 -0
  13. data/lib/facturama/models/csd.rb +14 -0
  14. data/lib/facturama/models/exception/facturama_exception.rb +18 -0
  15. data/lib/facturama/models/exception/model_exception.rb +11 -0
  16. data/lib/facturama/models/image.rb +11 -0
  17. data/lib/facturama/models/item.rb +25 -0
  18. data/lib/facturama/models/model.rb +75 -0
  19. data/lib/facturama/models/product.rb +27 -0
  20. data/lib/facturama/models/product_tax.rb +14 -0
  21. data/lib/facturama/models/receiver.rb +15 -0
  22. data/lib/facturama/models/serie.rb +13 -0
  23. data/lib/facturama/models/tax.rb +14 -0
  24. data/lib/facturama/models/tax_entity.rb +21 -0
  25. data/lib/facturama/models/tax_stamp.rb +12 -0
  26. data/lib/facturama/services/branch_office_service.rb +16 -0
  27. data/lib/facturama/services/catalog_service.rb +42 -0
  28. data/lib/facturama/services/cfdi_multi_service.rb +164 -0
  29. data/lib/facturama/services/cfdi_service.rb +172 -0
  30. data/lib/facturama/services/client_service.rb +19 -0
  31. data/lib/facturama/services/crud_service.rb +41 -0
  32. data/lib/facturama/services/csd_service.rb +16 -0
  33. data/lib/facturama/services/http_service.rb +152 -0
  34. data/lib/facturama/services/product_service.rb +16 -0
  35. data/lib/facturama/version.rb +4 -0
  36. data/lib/samples/sample_api.rb +17 -0
  37. data/lib/samples/sample_api_multi.rb +352 -0
  38. data/lib/samples/sample_api_web.rb +454 -0
  39. metadata +94 -0
@@ -0,0 +1,75 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'active_model'
3
+
4
+ module Facturama
5
+ module Models
6
+ class Model
7
+
8
+ include ActiveModel::Validations
9
+ include ActiveModel::Serializers::JSON
10
+
11
+ attr_accessor :all_errors
12
+
13
+ def initialize(values)
14
+ values.each_pair do |k, v|
15
+ send("#{k}=", v)
16
+ end
17
+ after_initialize
18
+ end
19
+
20
+ def after_initialize
21
+ end
22
+
23
+ def attributes
24
+ instance_values
25
+ end
26
+
27
+ def prepare_data
28
+ prepare_keys.to_json
29
+ end
30
+
31
+ def get_instance_values
32
+ instance_values.delete_if do |k, v|
33
+ %w(all_errors errors validation_context).include?(k)
34
+ end
35
+ end
36
+
37
+
38
+ class << self
39
+
40
+ def has_many_objects(association, class_name)
41
+ define_writer(association, class_name)
42
+ define_reader(association)
43
+ end
44
+
45
+ def has_one_object(association)
46
+ define_writer(association, association)
47
+ define_reader(association)
48
+ end
49
+
50
+ def define_writer(association, class_name)
51
+ class_eval <<-CODE
52
+ def #{association}=(value)
53
+ @#{association} =
54
+ if value.class.name == "Array"
55
+ value.collect do |val|
56
+ #{class_name.to_s.camelize}.new(val)
57
+ end
58
+ else
59
+ #{class_name.to_s.camelize}.new(value)
60
+ end
61
+ end
62
+ CODE
63
+ end
64
+
65
+ def define_reader(association)
66
+ attr_reader association
67
+ end
68
+
69
+ end
70
+
71
+
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Facturama
3
+
4
+ module Models
5
+
6
+ require_relative "product_tax"
7
+
8
+ class Product < Model
9
+ attr_accessor :Unit,
10
+ :UnitCode,
11
+ :IdentificationNumber,
12
+ :Name,
13
+ :Description,
14
+ :Price,
15
+ :CodeProdServ,
16
+ :CuentaPredial,
17
+ :Complement,
18
+ :Id,
19
+ :Taxes
20
+
21
+
22
+ validates :Unit, :Name, :Description, :Price, presence: true
23
+ #has_many_objects , :ProductTax
24
+ #has_many_objects :Taxes, ProductTax
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Facturama
3
+ module Models
4
+ class ProductTax < Model
5
+ attr_accessor :Name,
6
+ :Rate,
7
+ :IsRetention,
8
+ :IsFederalTax,
9
+ :IsQuota,
10
+ :Total
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Facturama
3
+ module Models
4
+ class Receiver < Model
5
+ attr_accessor :Id,
6
+ :Rfc,
7
+ :Name,
8
+ :CfdiUse,
9
+ :TaxResidence,
10
+ :TaxRegistrationNumber
11
+
12
+ validates :Rfc, presence: true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Facturama
3
+ module Models
4
+ class Serie < Model
5
+ attr_accessor :IdBranchOffice,
6
+ :Name,
7
+ :Description
8
+ :Folio
9
+
10
+ validates :IdBranchOffice, :Name, presence: true
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Facturama
3
+ module Models
4
+ class Tax < Model
5
+ attr_accessor :Total,
6
+ :Name,
7
+ :Base,
8
+ :Rate,
9
+ :Type,
10
+ :IsRetention,
11
+ :IsQuota
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Facturama
3
+ module Models
4
+ class TaxEntity < Model
5
+ attr_accessor :FiscalRegime,
6
+ :ComercialName,
7
+ :Rfc,
8
+ :TaxName,
9
+ :Email,
10
+ :Phone,
11
+ #:TaxAddress,
12
+ :PasswordSat,
13
+ :UrlLogo #solo Response
14
+
15
+ validates :FiscalRegime, :Rfc, :TaxName, :Email, presence: true
16
+ has_many_objects :TaxAddress, :Address #solo Response
17
+ has_many_objects :IssuedIn, :Address #solo Response
18
+ has_many_objects :Csd, :Csd #solo Response
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Facturama
3
+ module Models
4
+ class TaxStamp < Model
5
+ attr_accessor :Uuid,
6
+ :Date,
7
+ :CfdiSign,
8
+ :SatCertNumber,
9
+ :SatSign
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "crud_service"
2
+
3
+ module Facturama
4
+
5
+ module Services
6
+ class BranchOfficeService < CrudService
7
+
8
+ def initialize(connection_info )
9
+ super(connection_info, "BranchOffice")
10
+ end
11
+
12
+ end # class BranchOfficeService
13
+
14
+ end # module Services
15
+
16
+ end # module Facturama
@@ -0,0 +1,42 @@
1
+ require_relative "crud_service"
2
+
3
+ module Facturama
4
+
5
+ module Services
6
+ class CatalogService < CrudService
7
+
8
+ def initialize( connection_info )
9
+ super(connection_info, "catalogs")
10
+ end
11
+
12
+ def units(keyword = nil)
13
+ parameters = (keyword.to_s.empty?)? "" : "?keyword=" + keyword
14
+ get("units" + parameters)
15
+ end
16
+
17
+ def name_ids
18
+ get("NameIds")
19
+ end
20
+
21
+ def products_or_services(keyword)
22
+ get("ProductsOrServices?keyword="+keyword)
23
+ end
24
+
25
+ def currencies(keyword = nil)
26
+ parameters = (keyword.to_s.empty?)? "" : "?keyword=" + keyword
27
+ get("currencies" + parameters)
28
+ end
29
+
30
+ def payment_forms
31
+ get("paymentforms")
32
+ end
33
+
34
+ def payment_methods
35
+ get("paymentmethods")
36
+ end
37
+
38
+ end # class CatalogService
39
+
40
+ end # module Services
41
+
42
+ end # module Facturama
@@ -0,0 +1,164 @@
1
+ require_relative "crud_service"
2
+ require 'base64'
3
+
4
+ module Facturama
5
+
6
+ module Services
7
+ class CfdiMultiService < CrudService
8
+
9
+ def initialize( connection_info )
10
+ super(connection_info, "")
11
+ end
12
+
13
+
14
+ # ------------------------ CRUD ------------------------
15
+
16
+
17
+ def create(model)
18
+ post(model, "api-lite/2/cfdis")
19
+ end
20
+
21
+
22
+ def remove(id)
23
+
24
+ if !id.nil? && id != ""
25
+ delete("api-lite/cfdis/" + id )
26
+ else
27
+ raise( FacturamaException("El Id del cfdi a eliminar es obligatorio") )
28
+ end
29
+ end
30
+
31
+
32
+ def retrieve(id)
33
+ get("api-lite/cfdis/" + id )
34
+ end
35
+
36
+
37
+ # ------------------------ DESCARGA DE ARCHIVOS (PDF, XML, HTML) ------------------------
38
+
39
+
40
+
41
+ # Obtiene un archivo referente a un CFDI del tipo "Issued"
42
+ # @param id Identificador del CFDI
43
+ # @param format Formato deseado ( pdf | html | xml )
44
+ # @param type Tipo de comprobante ( payroll | received | issued )
45
+ # @return Archivo en cuestion
46
+ def get_file(id, format, type)
47
+ resource = "cfdi/" + format + "/" + type + "/" + id
48
+ get(resource)
49
+ end
50
+
51
+
52
+ # Decodifica y guarda un archivo base64 en una ruta
53
+ def save_file(file_path, file_content_base64)
54
+ file_content_decoded = Base64.decode64(file_content_base64)
55
+ File.open(file_path, "wb") do |f|
56
+ f.write(file_content_decoded)
57
+ end
58
+ end
59
+
60
+
61
+ def save_pdf(file_path, id, type = Facturama::InvoiceType::ISSUED_LITE)
62
+ file_content = get_file(id, Facturama::FileFormat::PDF, type)
63
+ save_file(file_path, file_content['Content'])
64
+ end
65
+
66
+ def save_xml(file_path, id, type = Facturama::InvoiceType::ISSUED_LITE)
67
+ file_content = get_file(id, Facturama::FileFormat::XML, type)
68
+ save_file(file_path, file_content['Content'])
69
+ end
70
+
71
+ def save_html(file_path, id, type = Facturama::InvoiceType::ISSUED_LITE)
72
+ file_content = get_file(id, Facturama::FileFormat::HTML, type)
73
+ save_file(file_path, file_content['Content'])
74
+ end
75
+
76
+
77
+
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
+
85
+ resource = "api-lite/cfdis?status=" + status + "&keyword=" + keyword
86
+ get(resource)
87
+ end
88
+
89
+
90
+
91
+ # Listado de Cfdi filtrando por palabra RFC
92
+ def list_by_rfc(rfc,
93
+ status = Facturama::CfdiStatus::ACTIVE,
94
+ type = Facturama::InvoiceType::ISSUED)
95
+
96
+ resource = "api-lite/cfdis?status=" + status + "&rfc=" + rfc
97
+ get(resource)
98
+ end
99
+
100
+
101
+
102
+
103
+ # Listado con todas las opciones posibles
104
+ def list(folio_start = -1, folio_end = -1,
105
+ rfc = nil, tax_entity_name = nil,
106
+ date_start = nil, date_end = nil,
107
+ id_branch = nil, serie = nil,
108
+ status = Facturama::CfdiStatus::ACTIVE,
109
+ type = Facturama::InvoiceType::ISSUED)
110
+
111
+ resource = "api-lite/cfdis?type=" + type + "&status=" + status
112
+
113
+ if folio_start > -1
114
+ resource += "&folioStart=" + folio_start
115
+ end
116
+
117
+ if folio_end > -1
118
+ resource += "&folioEnd=" + folio_end
119
+ end
120
+
121
+ if rfc != nil
122
+ resource += "&rfc=" + rfc
123
+ end
124
+
125
+ if tax_entity_name != nil
126
+ resource += "&taxEntityName=" + tax_entity_name
127
+ end
128
+
129
+ if date_start != nil
130
+ resource += "&dateStart=" + date_start
131
+ end
132
+
133
+ if date_end != nil
134
+ resource += "&dateEnd=" + date_end
135
+ end
136
+
137
+ if id_branch != nil
138
+ resource += "&idBranch=" + id_branch
139
+ end
140
+
141
+ if serie != nil
142
+ resource += "&serie=" + serie
143
+ end
144
+
145
+
146
+ get(resource)
147
+ end
148
+
149
+
150
+
151
+ # ------------------------ ENVIO POR CORREO ------------------------
152
+
153
+ # Envía el CFDI por correo, con el asunto especificado
154
+ def send_by_mail(id, email, subject, type = Facturama::InvoiceType::ISSUED_LITE)
155
+ response = post(nil,"cfdi?cfdiType=#{type}&cfdiId=#{id}&email=#{email}&subject=#{subject}")
156
+ !!response['success']
157
+ end
158
+
159
+
160
+ end # class CfdiService
161
+
162
+ end # module Services
163
+
164
+ end # module Facturama
@@ -0,0 +1,172 @@
1
+ require_relative "crud_service"
2
+ require 'base64'
3
+
4
+ module Facturama
5
+
6
+ module Services
7
+ class CfdiService < CrudService
8
+
9
+ def initialize( connection_info )
10
+ super(connection_info, "")
11
+ end
12
+
13
+
14
+ # ------------------------ CRUD ------------------------
15
+
16
+
17
+ def create(model)
18
+ post(model, "2/cfdis")
19
+ end
20
+
21
+
22
+ def remove(id)
23
+
24
+ if !id.nil? && id != ""
25
+ delete("cfdi/" + id + "?type=issued")
26
+ else
27
+ raise( FacturamaException("El Id del cfdi a eliminar es obligatorio") )
28
+ end
29
+ end
30
+
31
+
32
+ def retrieve(id, type = nil)
33
+
34
+ if type.nil?
35
+ str_type = "Issued"
36
+ else
37
+ str_type = type
38
+ end
39
+
40
+ get("cfdi/" + id + "?type=#{str_type}")
41
+ end
42
+
43
+
44
+ # ------------------------ DESCARGA DE ARCHIVOS (PDF, XML, HTML) ------------------------
45
+
46
+
47
+
48
+ # Obtiene un archivo referente a un CFDI del tipo "Issued"
49
+ # @param id Identificador del CFDI
50
+ # @param format Formato deseado ( pdf | html | xml )
51
+ # @param type Tipo de comprobante ( payroll | received | issued )
52
+ # @return Archivo en cuestion
53
+ def get_file(id, format, type)
54
+ resource = "api/cfdi/" + format + "/" + type + "/" + id
55
+ get(resource)
56
+ end
57
+
58
+
59
+ # Decodifica y guarda un archivo base64 en una ruta
60
+ def save_file(file_path, file_content_base64)
61
+ file_content_decoded = Base64.decode64(file_content_base64)
62
+ File.open(file_path, "wb") do |f|
63
+ f.write(file_content_decoded)
64
+ end
65
+ end
66
+
67
+
68
+ def save_pdf(file_path, id, type = Facturama::InvoiceType::ISSUED)
69
+ file_content = get_file(id, Facturama::FileFormat::PDF, type)
70
+ save_file(file_path, file_content['Content'])
71
+ end
72
+
73
+ def save_xml(file_path, id, type = Facturama::InvoiceType::ISSUED)
74
+ file_content = get_file(id, Facturama::FileFormat::XML, type)
75
+ save_file(file_path, file_content['Content'])
76
+ end
77
+
78
+ def save_html(file_path, id, type = Facturama::InvoiceType::ISSUED)
79
+ file_content = get_file(id, Facturama::FileFormat::HTML, type)
80
+ save_file(file_path, file_content['Content'])
81
+ end
82
+
83
+
84
+
85
+
86
+ # ------------------------ LISTADO DE CFDIS ------------------------
87
+
88
+ # Listado de Cfdi filtrando por palabra clave
89
+ def list_by_keyword(keyword,
90
+ status = Facturama::CfdiStatus::ACTIVE,
91
+ type = Facturama::InvoiceType::ISSUED)
92
+
93
+ resource = "cfdi?type=" + type + "&status=" + status + "&keyword=" + keyword
94
+ get(resource)
95
+ end
96
+
97
+
98
+
99
+ # Listado de Cfdi filtrando por palabra RFC
100
+ def list_by_rfc(rfc,
101
+ status = Facturama::CfdiStatus::ACTIVE,
102
+ type = Facturama::InvoiceType::ISSUED)
103
+
104
+ resource = "cfdi?type=" + type + "&status=" + status + "&rfc=" + rfc
105
+ get(resource)
106
+ end
107
+
108
+
109
+
110
+
111
+ # Listado con todas las opciones posibles
112
+ def list(folio_start = -1, folio_end = -1,
113
+ rfc = nil, tax_entity_name = nil,
114
+ date_start = nil, date_end = nil,
115
+ id_branch = nil, serie = nil,
116
+ status = Facturama::CfdiStatus::ACTIVE,
117
+ type = Facturama::InvoiceType::ISSUED)
118
+
119
+ resource = "cfdi?type=" + type + "&status=" + status
120
+
121
+ if folio_start > -1
122
+ resource += "&folioStart=" + folio_start
123
+ end
124
+
125
+ if folio_end > -1
126
+ resource += "&folioEnd=" + folio_end
127
+ end
128
+
129
+ if rfc != nil
130
+ resource += "&rfc=" + rfc
131
+ end
132
+
133
+ if tax_entity_name != nil
134
+ resource += "&taxEntityName=" + tax_entity_name
135
+ end
136
+
137
+ if date_start != nil
138
+ resource += "&dateStart=" + date_start
139
+ end
140
+
141
+ if date_end != nil
142
+ resource += "&dateEnd=" + date_end
143
+ end
144
+
145
+ if id_branch != nil
146
+ resource += "&idBranch=" + id_branch
147
+ end
148
+
149
+ if serie != nil
150
+ resource += "&serie=" + serie
151
+ end
152
+
153
+
154
+ get(resource)
155
+ end
156
+
157
+
158
+
159
+ # ------------------------ ENVIO POR CORREO ------------------------
160
+
161
+ # Envía el CFDI por correo, con el asunto especificado
162
+ def send_by_mail(id, email, subject, type = Facturama::InvoiceType::ISSUED)
163
+ response = post(nil,"cfdi?cfdiType=#{type}&cfdiId=#{id}&email=#{email}&subject=#{subject}")
164
+ !!response['success']
165
+ end
166
+
167
+
168
+ end # class CfdiService
169
+
170
+ end # module Services
171
+
172
+ end # module Facturama