facturama 0.0.1
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 +7 -0
- data/lib/facturama.rb +56 -0
- data/lib/facturama/facturama_api_multi.rb +37 -0
- data/lib/facturama/facturama_api_web.rb +55 -0
- data/lib/facturama/models/address.rb +16 -0
- data/lib/facturama/models/branch_office.rb +14 -0
- data/lib/facturama/models/cfdi.rb +80 -0
- data/lib/facturama/models/cfdi_relation.rb +10 -0
- data/lib/facturama/models/cfdi_relations.rb +12 -0
- data/lib/facturama/models/client.rb +19 -0
- data/lib/facturama/models/complement.rb +8 -0
- data/lib/facturama/models/connection_info.rb +36 -0
- data/lib/facturama/models/csd.rb +14 -0
- data/lib/facturama/models/exception/facturama_exception.rb +18 -0
- data/lib/facturama/models/exception/model_exception.rb +11 -0
- data/lib/facturama/models/image.rb +11 -0
- data/lib/facturama/models/item.rb +25 -0
- data/lib/facturama/models/model.rb +75 -0
- data/lib/facturama/models/product.rb +27 -0
- data/lib/facturama/models/product_tax.rb +14 -0
- data/lib/facturama/models/receiver.rb +15 -0
- data/lib/facturama/models/serie.rb +13 -0
- data/lib/facturama/models/tax.rb +14 -0
- data/lib/facturama/models/tax_entity.rb +21 -0
- data/lib/facturama/models/tax_stamp.rb +12 -0
- data/lib/facturama/services/branch_office_service.rb +16 -0
- data/lib/facturama/services/catalog_service.rb +42 -0
- data/lib/facturama/services/cfdi_multi_service.rb +164 -0
- data/lib/facturama/services/cfdi_service.rb +172 -0
- data/lib/facturama/services/client_service.rb +19 -0
- data/lib/facturama/services/crud_service.rb +41 -0
- data/lib/facturama/services/csd_service.rb +16 -0
- data/lib/facturama/services/http_service.rb +152 -0
- data/lib/facturama/services/product_service.rb +16 -0
- data/lib/facturama/version.rb +4 -0
- data/lib/samples/sample_api.rb +17 -0
- data/lib/samples/sample_api_multi.rb +352 -0
- data/lib/samples/sample_api_web.rb +454 -0
- 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,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,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
|