colppy 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +36 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +38 -0
- data/Rakefile +39 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/colppy.gemspec +30 -0
- data/lib/colppy.rb +22 -0
- data/lib/colppy/client.rb +69 -0
- data/lib/colppy/core/gateway.rb +75 -0
- data/lib/colppy/core/services.rb +72 -0
- data/lib/colppy/core/support/hash.rb +49 -0
- data/lib/colppy/digest.rb +16 -0
- data/lib/colppy/errors.rb +7 -0
- data/lib/colppy/resource.rb +83 -0
- data/lib/colppy/resources/company.rb +123 -0
- data/lib/colppy/resources/customer.rb +169 -0
- data/lib/colppy/resources/product.rb +152 -0
- data/lib/colppy/resources/sell_invoice.rb +343 -0
- data/lib/colppy/resources/user.rb +97 -0
- data/lib/colppy/version.rb +3 -0
- metadata +174 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
module Colppy
|
2
|
+
module Core
|
3
|
+
SERVICES = {
|
4
|
+
company: {
|
5
|
+
list: {
|
6
|
+
provision: "Empresa",
|
7
|
+
operacion: "listar_empresa"
|
8
|
+
},
|
9
|
+
read: {
|
10
|
+
provision: "Empresa",
|
11
|
+
operacion: "leer_empresa"
|
12
|
+
}
|
13
|
+
},
|
14
|
+
customer: {
|
15
|
+
list: {
|
16
|
+
provision: "Cliente",
|
17
|
+
operacion: "listar_cliente"
|
18
|
+
},
|
19
|
+
read: {
|
20
|
+
provision: "Cliente",
|
21
|
+
operacion: "leer_cliente"
|
22
|
+
},
|
23
|
+
create: {
|
24
|
+
provision: "Cliente",
|
25
|
+
operacion: "alta_cliente"
|
26
|
+
},
|
27
|
+
update: {
|
28
|
+
provision: "Cliente",
|
29
|
+
operacion: "editar_cliente"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
product: {
|
33
|
+
list: {
|
34
|
+
provision: "Inventario",
|
35
|
+
operacion: "listar_itemsinventario"
|
36
|
+
},
|
37
|
+
create: {
|
38
|
+
provision: "Inventario",
|
39
|
+
operacion: "alta_iteminventario"
|
40
|
+
},
|
41
|
+
update: {
|
42
|
+
provision: "Inventario",
|
43
|
+
operacion: "editar_iteminventario"
|
44
|
+
}
|
45
|
+
},
|
46
|
+
sell_invoice: {
|
47
|
+
list: {
|
48
|
+
provision: "FacturaVenta",
|
49
|
+
operacion: "listar_facturasventa"
|
50
|
+
},
|
51
|
+
read: {
|
52
|
+
provision: "FacturaVenta",
|
53
|
+
operacion: "leer_facturaventa"
|
54
|
+
},
|
55
|
+
create: {
|
56
|
+
provision: "FacturaVenta",
|
57
|
+
operacion: "alta_facturaventa"
|
58
|
+
}
|
59
|
+
},
|
60
|
+
user: {
|
61
|
+
sign_in: {
|
62
|
+
provision: "Usuario",
|
63
|
+
operacion: "iniciar_sesion"
|
64
|
+
},
|
65
|
+
sign_out: {
|
66
|
+
provision: "Usuario",
|
67
|
+
operacion: "cerrar_sesion"
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}.freeze
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# # Taken from https://github.com/futurechimp/plissken because that gem
|
2
|
+
# # has a dependency on symbolize -> Active**
|
3
|
+
|
4
|
+
module Colppy
|
5
|
+
module Core
|
6
|
+
# Colppy::Core::Hash.snakecase_keys(value)
|
7
|
+
module Hash
|
8
|
+
extend self
|
9
|
+
# Recursively converts CamelCase and camelBack JSON-style hash keys to
|
10
|
+
# Rubyish snake_case, suitable for use during instantiation of Ruby
|
11
|
+
# model attributes.
|
12
|
+
#
|
13
|
+
def snakecase_keys(value)
|
14
|
+
case value
|
15
|
+
when(Array)
|
16
|
+
value.map { |v| snakecase_keys(v) }
|
17
|
+
when(::Hash)
|
18
|
+
snake_hash(value)
|
19
|
+
else
|
20
|
+
value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def snake_hash(value)
|
27
|
+
::Hash[value.map { |k, v| [snake_key(k).to_sym, snakecase_keys(v)] }]
|
28
|
+
end
|
29
|
+
|
30
|
+
def snake_key(k)
|
31
|
+
if k.is_a? Symbol
|
32
|
+
snakecase(k.to_s).to_sym
|
33
|
+
elsif k.is_a? String
|
34
|
+
snakecase(k)
|
35
|
+
else
|
36
|
+
k # Can't snakify anything except strings and symbols
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def snakecase(string)
|
41
|
+
string.gsub(/::/, '/')
|
42
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
43
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
44
|
+
.tr('-', '_')
|
45
|
+
.downcase
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Colppy
|
2
|
+
module Digest
|
3
|
+
module_function
|
4
|
+
|
5
|
+
MD5_DIGEST = OpenSSL::Digest.new("md5").freeze
|
6
|
+
|
7
|
+
def md5(string)
|
8
|
+
return string if valid_md5?(string)
|
9
|
+
MD5_DIGEST.hexdigest(string)
|
10
|
+
end
|
11
|
+
|
12
|
+
def valid_md5?(string)
|
13
|
+
!!(%r{^[a-f0-9]{32}$}i =~ string)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Colppy
|
2
|
+
class Resource
|
3
|
+
VALID_INVOICE_TYPES = %w(A B C E Z I M X)
|
4
|
+
|
5
|
+
class << self
|
6
|
+
protected
|
7
|
+
|
8
|
+
def parse_list_response(results, total, call_parameters)
|
9
|
+
per_page = call_parameters[:limit] || 50
|
10
|
+
offset = call_parameters[:start] || 0
|
11
|
+
page, total_pages = pages_calculation(offset, per_page, total)
|
12
|
+
{
|
13
|
+
offset: offset,
|
14
|
+
total: total,
|
15
|
+
page: page,
|
16
|
+
per_page: per_page,
|
17
|
+
total_pages: total_pages,
|
18
|
+
results: results
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def pages_calculation(offset, per_page, total)
|
25
|
+
total_pages = ( total.to_f / per_page.to_f ).ceil
|
26
|
+
remaining_pages = ((total - offset).to_f / per_page.to_f).floor
|
27
|
+
[(total_pages - remaining_pages), total_pages]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
formatted_attrs = attr_inspect.map do |attr|
|
33
|
+
"#{attr}: #{send(attr).inspect}"
|
34
|
+
end
|
35
|
+
"#<#{self.class.name} #{formatted_attrs.join(", ")}>"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def attr_inspect
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid_date(date_string)
|
44
|
+
return today_date_string if date_string.nil? || date_string.empty?
|
45
|
+
|
46
|
+
parsed_date = Date.parse(date_string)
|
47
|
+
if parsed_date <= Date.today
|
48
|
+
date_string
|
49
|
+
else
|
50
|
+
today_date_string
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def today_date_string
|
55
|
+
Date.today.strftime("%d-%m-%Y")
|
56
|
+
end
|
57
|
+
|
58
|
+
def ensure_client_valid!
|
59
|
+
unless @client && @client.is_a?(Colppy::Client)
|
60
|
+
raise ResourceError.new(
|
61
|
+
"You should provide a client, and it should be a Colppy::Client instance"
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def ensure_company_valid!
|
67
|
+
unless @company && @company.is_a?(Colppy::Company)
|
68
|
+
raise ResourceError.new(
|
69
|
+
"You should provide a company, and it should be a Colppy::Company instance"
|
70
|
+
)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def ensure_customer_valid!
|
75
|
+
unless @customer && @customer.is_a?(Colppy::Customer)
|
76
|
+
raise ResourceError.new(
|
77
|
+
"You should provide a customer, and it should be a Colppy::Customer instance"
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Colppy
|
2
|
+
module CompanyActions
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def companies
|
6
|
+
@companies ||= Company.all(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class Company < Resource
|
12
|
+
attr_reader :id, :name
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def all(client)
|
16
|
+
list(client)
|
17
|
+
end
|
18
|
+
|
19
|
+
def list(client, parameters = {})
|
20
|
+
response = client.call(
|
21
|
+
:company,
|
22
|
+
:list,
|
23
|
+
parameters.merge(client.session_params)
|
24
|
+
)
|
25
|
+
if response[:success]
|
26
|
+
results = response[:data].map do |params|
|
27
|
+
new(params.merge(client: client))
|
28
|
+
end
|
29
|
+
parse_list_response(results, response[:total].to_i, parameters)
|
30
|
+
else
|
31
|
+
response
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(client: nil, **params)
|
37
|
+
@client = client if client && client.is_a?(Colppy::Client)
|
38
|
+
@id = params.delete(:IdEmpresa)
|
39
|
+
@name = params.delete(:razonSocial)
|
40
|
+
@extras = params
|
41
|
+
end
|
42
|
+
|
43
|
+
def customers(params = {})
|
44
|
+
ensure_client_valid!
|
45
|
+
|
46
|
+
if params.empty?
|
47
|
+
Customer.all(@client, self)
|
48
|
+
else
|
49
|
+
Customer.list(@client, self, params)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def customer_by_id(id)
|
54
|
+
ensure_client_valid!
|
55
|
+
|
56
|
+
Customer.get(@client, self, id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def products(params = {})
|
60
|
+
ensure_client_valid!
|
61
|
+
|
62
|
+
if params.empty?
|
63
|
+
Product.all(@client, self)
|
64
|
+
else
|
65
|
+
Product.list(@client, self, params)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
alias :customer :customer_by_id
|
69
|
+
|
70
|
+
def product_by_sku(sku)
|
71
|
+
ensure_client_valid!
|
72
|
+
|
73
|
+
params = {
|
74
|
+
filter: [
|
75
|
+
{ field: "codigo", op: "=", value: sku }
|
76
|
+
]
|
77
|
+
}
|
78
|
+
response = Product.list(@client, self, params)
|
79
|
+
response[:results].last
|
80
|
+
end
|
81
|
+
|
82
|
+
def product_by_id(id)
|
83
|
+
ensure_client_valid!
|
84
|
+
|
85
|
+
params = {
|
86
|
+
filter: [
|
87
|
+
{ field: "idItem", op: "=", value: id }
|
88
|
+
]
|
89
|
+
}
|
90
|
+
response = Product.list(@client, self, params)
|
91
|
+
response[:results].last
|
92
|
+
end
|
93
|
+
alias :product :product_by_id
|
94
|
+
|
95
|
+
def sell_invoices(params = {})
|
96
|
+
ensure_client_valid!
|
97
|
+
|
98
|
+
if params.empty?
|
99
|
+
SellInvoice.all(@client, self)
|
100
|
+
else
|
101
|
+
SellInvoice.list(@client, self, params)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def sell_invoice_by_id(id)
|
106
|
+
ensure_client_valid!
|
107
|
+
|
108
|
+
SellInvoice.get(@client, self, id)
|
109
|
+
end
|
110
|
+
alias :sell_invoice :sell_invoice_by_id
|
111
|
+
|
112
|
+
def params
|
113
|
+
{ idEmpresa: @id }
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def attr_inspect
|
119
|
+
[:id, :name]
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module Colppy
|
2
|
+
class Customer < Resource
|
3
|
+
attr_reader :id, :name, :data
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def all(client, company)
|
7
|
+
list(client, company)
|
8
|
+
end
|
9
|
+
|
10
|
+
def list(client, company, parameters = {})
|
11
|
+
call_parameters = base_params.merge(parameters)
|
12
|
+
response = client.call(
|
13
|
+
:customer,
|
14
|
+
:list,
|
15
|
+
extended_parameters(client, company, call_parameters)
|
16
|
+
)
|
17
|
+
if response[:success]
|
18
|
+
results = response[:data].map do |params|
|
19
|
+
new(params.merge(client: client, company: company))
|
20
|
+
end
|
21
|
+
parse_list_response(results, response[:total].to_i, call_parameters)
|
22
|
+
else
|
23
|
+
response
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def get(client, company, id)
|
28
|
+
response = client.call(
|
29
|
+
:customer,
|
30
|
+
:read,
|
31
|
+
extended_parameters(client, company, { idCliente: id })
|
32
|
+
)
|
33
|
+
if response[:success]
|
34
|
+
new(response[:data].merge(client: client, company: company))
|
35
|
+
else
|
36
|
+
response
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def extended_parameters(client, company, parameters)
|
43
|
+
[ client.session_params,
|
44
|
+
company.params,
|
45
|
+
parameters
|
46
|
+
].inject(&:merge)
|
47
|
+
end
|
48
|
+
|
49
|
+
def base_params
|
50
|
+
{
|
51
|
+
filter:[],
|
52
|
+
order: [{
|
53
|
+
field: "RazonSocial",
|
54
|
+
dir: "asc"
|
55
|
+
}]
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize(client: nil, company: nil, **params)
|
62
|
+
@client = client if client && client.is_a?(Colppy::Client)
|
63
|
+
@company = company if company && company.is_a?(Colppy::Company)
|
64
|
+
@id = params.delete(:idCliente)
|
65
|
+
@name = params.delete(:RazonSocial)
|
66
|
+
@data = params
|
67
|
+
end
|
68
|
+
|
69
|
+
def new?
|
70
|
+
id.nil? || id.empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
def save
|
74
|
+
ensure_client_valid! && ensure_company_valid!
|
75
|
+
|
76
|
+
response = @client.call(
|
77
|
+
:customer,
|
78
|
+
operation,
|
79
|
+
save_parameters
|
80
|
+
)
|
81
|
+
if response[:success]
|
82
|
+
response_data = response[:data]
|
83
|
+
case operation
|
84
|
+
when :create
|
85
|
+
@id = response_data[:idCliente]
|
86
|
+
when :update
|
87
|
+
@data[:NombreFantasia] = response_data[:nombreCliente]
|
88
|
+
end
|
89
|
+
self
|
90
|
+
else
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def name=(new_name)
|
96
|
+
@name = new_name
|
97
|
+
end
|
98
|
+
|
99
|
+
def []=(key, value)
|
100
|
+
key_sym = key.to_sym
|
101
|
+
if protected_data_keys.include?(key_sym)
|
102
|
+
raise ResourceError.new("You cannot change any of this values: #{protected_data_keys.join(", ")} manually")
|
103
|
+
end
|
104
|
+
@data[key_sym] = value
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def attr_inspect
|
110
|
+
[:id, :name]
|
111
|
+
end
|
112
|
+
|
113
|
+
def protected_data_keys
|
114
|
+
[:idUsuario, :idCliente, :idEmpresa]
|
115
|
+
end
|
116
|
+
|
117
|
+
def operation
|
118
|
+
new? ? :create : :update
|
119
|
+
end
|
120
|
+
|
121
|
+
def save_parameters
|
122
|
+
[
|
123
|
+
@client.session_params,
|
124
|
+
info_general: general_info_params,
|
125
|
+
info_otra: other_info_params
|
126
|
+
].inject(&:merge)
|
127
|
+
end
|
128
|
+
|
129
|
+
def general_info_params
|
130
|
+
{
|
131
|
+
idUsuario: @client.username,
|
132
|
+
idCliente: id || "",
|
133
|
+
idEmpresa: @company.id,
|
134
|
+
NombreFantasia: @data[:NombreFantasia] || "",
|
135
|
+
RazonSocial: name || "",
|
136
|
+
CUIT: @data[:CUIT] || "",
|
137
|
+
DirPostal: @data[:DirPostal] || "",
|
138
|
+
DirPostalCiudad: @data[:DirPostalCiudad] || "",
|
139
|
+
DirPostalCodigoPostal: @data[:DirPostalCodigoPostal] || "",
|
140
|
+
DirPostalProvincia: @data[:DirPostalProvincia] || "",
|
141
|
+
DirPostalPais: @data[:DirPostalPais] || "Argentina",
|
142
|
+
Telefono: @data[:Telefono] || "",
|
143
|
+
Email: @data[:Email] || ""
|
144
|
+
}
|
145
|
+
end
|
146
|
+
|
147
|
+
def other_info_params
|
148
|
+
{
|
149
|
+
Activo: @data[:Activo] || "1",
|
150
|
+
FechaAlta: @data[:FechaAlta] || "",
|
151
|
+
DirFiscal: @data[:DirFiscal] || "",
|
152
|
+
DirFiscalCiudad: @data[:DirFiscalCiudad] || "",
|
153
|
+
DirFiscalCodigoPostal: @data[:DirFiscalCodigoPostal] || "",
|
154
|
+
DirFiscalProvincia: @data[:DirFiscalProvincia] || "",
|
155
|
+
DirFiscalPais: @data[:DirFiscalPais] || "",
|
156
|
+
idCondicionPago: @data[:idCondicionPago] || "",
|
157
|
+
idCondicionIva: @data[:idCondicionIva] || "",
|
158
|
+
porcentajeIVA: @data[:porcentajeIVA] || "21",
|
159
|
+
idPlanCuenta: @data[:idPlanCuenta] || "",
|
160
|
+
CuentaCredito: @data[:CuentaCredito] || "",
|
161
|
+
DirEnvio: @data[:DirEnvio] || "",
|
162
|
+
DirEnvioCiudad: @data[:DirEnvioCiudad] || "",
|
163
|
+
DirEnvioCodigoPostal: @data[:DirEnvioCodigoPostal] || "",
|
164
|
+
DirEnvioProvincia: @data[:DirEnvioProvincia] || "",
|
165
|
+
DirEnvioPais: @data[:DirEnvioPais] || ""
|
166
|
+
}
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|