moloni_api 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/.github/workflows/main.yml +18 -0
- data/.gitignore +18 -0
- data/.rspec +3 -0
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +0 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Dockerfile +11 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +12 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +7 -0
- data/lib/moloni_api/api/config/property.rb +25 -0
- data/lib/moloni_api/api/config/property_set.rb +119 -0
- data/lib/moloni_api/api/config.rb +101 -0
- data/lib/moloni_api/api.rb +135 -0
- data/lib/moloni_api/api_exceptions.rb +14 -0
- data/lib/moloni_api/client.rb +250 -0
- data/lib/moloni_api/configuration.rb +28 -0
- data/lib/moloni_api/constants.rb +62 -0
- data/lib/moloni_api/http_status_codes.rb +13 -0
- data/lib/moloni_api/models/product.rb +120 -0
- data/lib/moloni_api/version.rb +5 -0
- data/lib/moloni_api.rb +89 -0
- data/moloni_api.gemspec +40 -0
- metadata +103 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'api_exceptions'
|
4
|
+
require_relative 'configuration'
|
5
|
+
require_relative 'constants'
|
6
|
+
require_relative 'http_status_codes'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
module MoloniApi
|
10
|
+
# Core class responsible for api interface operations
|
11
|
+
class API
|
12
|
+
include ApiExceptions
|
13
|
+
include Constants
|
14
|
+
include HttpStatusCodes
|
15
|
+
|
16
|
+
attr_reader(*MoloniApi.configuration.property_names, :token, :endpoint)
|
17
|
+
|
18
|
+
attr_accessor :current_options
|
19
|
+
|
20
|
+
# Callback to update current configuration options
|
21
|
+
class_eval do
|
22
|
+
MoloniApi.configuration.property_names.each do |key|
|
23
|
+
define_method "#{key}=" do |arg|
|
24
|
+
instance_variable_set("@#{key}", arg)
|
25
|
+
current_options.merge!({ "#{key}": arg })
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
API_ENDPOINT = 'https://api.moloni.pt/sandbox/'
|
31
|
+
HTTP_STATUS_MAPPING = {
|
32
|
+
HTTP_BAD_REQUEST_CODE => BadRequestError,
|
33
|
+
HTTP_UNAUTHORIZED_CODE => UnauthorizedError,
|
34
|
+
HTTP_FORBIDDEN_CODE => ForbiddenError,
|
35
|
+
HTTP_NOT_FOUND_CODE => NotFoundError,
|
36
|
+
HTTP_UNPROCESSABLE_ENTITY_CODE => UnprocessableEntityError,
|
37
|
+
'default' => ApiError
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
# Create new API
|
41
|
+
#
|
42
|
+
# @api public
|
43
|
+
def initialize(options = {}, &block)
|
44
|
+
opts = MoloniApi.configuration.fetch.merge(options)
|
45
|
+
@current_options = opts
|
46
|
+
|
47
|
+
MoloniApi.configuration.property_names.each do |key|
|
48
|
+
send("#{key}=", opts[key])
|
49
|
+
end
|
50
|
+
@api_access_token = opts[:access_token] # If not provided will need to ask for credentials
|
51
|
+
@api_client_id = opts[:client_id] || ENV['MOLONI_API_CLIENT_ID']
|
52
|
+
@api_client_secret = opts[:client_secret] || ENV['MOLONI_API_CLIENT_SECRET']
|
53
|
+
@api_endpoint = opts[:endpoint] || ENV['MOLONI_API_ENDPOINT'] || API_ENDPOINT
|
54
|
+
|
55
|
+
yield_or_eval(&block) if block_given?
|
56
|
+
end
|
57
|
+
|
58
|
+
# Call block with argument
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
def yield_or_eval(&block)
|
62
|
+
return unless block
|
63
|
+
|
64
|
+
block.arity.positive? ? yield(self) : instance_eval(&block)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def client
|
70
|
+
# provide your own logger
|
71
|
+
logger = Logger.new $stderr
|
72
|
+
logger.level = Logger::DEBUG
|
73
|
+
@client ||= Faraday.new(@api_endpoint) do |client|
|
74
|
+
client.request :url_encoded
|
75
|
+
#client.request :json
|
76
|
+
#client.response :json
|
77
|
+
client.adapter Faraday.default_adapter
|
78
|
+
client.response :logger, logger
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def request(http_method:, endpoint:, params: {}, query_params: {}, add_access_token: true)
|
83
|
+
if add_access_token
|
84
|
+
query_params[:access_token] = @api_access_token
|
85
|
+
query_params[:json] = true
|
86
|
+
end
|
87
|
+
response = client.public_send(http_method, endpoint) do |req|
|
88
|
+
req.headers['Content-Type'] = 'application/json'
|
89
|
+
req.params = query_params
|
90
|
+
req.body = params.to_json if params.size
|
91
|
+
end
|
92
|
+
logger = Logger.new $stderr
|
93
|
+
logger.debug('Response: ' + response.body)
|
94
|
+
|
95
|
+
if response_successful?(response)
|
96
|
+
parsed_response = Oj.load(response.body)
|
97
|
+
return parsed_response
|
98
|
+
end
|
99
|
+
|
100
|
+
raise error_class(response), "Code: #{response.status}, response: #{response.body}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def error_class(response)
|
104
|
+
if HTTP_STATUS_MAPPING.include?(response.status)
|
105
|
+
HTTP_STATUS_MAPPING[response.status]
|
106
|
+
else
|
107
|
+
HTTP_STATUS_MAPPING['default']
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def response_successful?(response)
|
112
|
+
response.status == HTTP_OK_CODE
|
113
|
+
end
|
114
|
+
|
115
|
+
# Responds to attribute query or attribute clear
|
116
|
+
#
|
117
|
+
# @api private
|
118
|
+
def method_missing(method_name, *args, &block)
|
119
|
+
# :nodoc:
|
120
|
+
case method_name.to_s
|
121
|
+
when /^(.*)\?$/
|
122
|
+
!!send(Regexp.last_match(1).to_s)
|
123
|
+
when /^clear_(.*)$/
|
124
|
+
send("#{Regexp.last_match(1)}=", nil)
|
125
|
+
else
|
126
|
+
super
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def respond_to_missing?(method_name, include_private = false)
|
131
|
+
method_name.to_s.start_with?('clear_') || super
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
# mapi = MoloniApi.new(token: )
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoloniApi
|
4
|
+
module ApiExceptions
|
5
|
+
APIExceptionError = Class.new(StandardError)
|
6
|
+
BadRequestError = Class.new(APIExceptionError)
|
7
|
+
UnauthorizedError = Class.new(APIExceptionError)
|
8
|
+
ForbiddenError = Class.new(APIExceptionError)
|
9
|
+
ApiRequestsQuotaReachedError = Class.new(APIExceptionError)
|
10
|
+
NotFoundError = Class.new(APIExceptionError)
|
11
|
+
UnprocessableEntityError = Class.new(APIExceptionError)
|
12
|
+
ApiError = Class.new(APIExceptionError)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'logger'
|
5
|
+
require_relative 'api'
|
6
|
+
require_relative 'models/product'
|
7
|
+
|
8
|
+
module MoloniApi
|
9
|
+
# Main client class that implements communication with the API
|
10
|
+
# other_params - view documentation for additional options:
|
11
|
+
# https://www.moloni.pt/dev/endpoints/
|
12
|
+
# - qty
|
13
|
+
# - offset
|
14
|
+
# global:
|
15
|
+
# - access_token
|
16
|
+
# - json
|
17
|
+
# - human_errors
|
18
|
+
class Client < API
|
19
|
+
|
20
|
+
attr_accessor :api_access_token, :api_refresh_token
|
21
|
+
|
22
|
+
def authenticate(user_username, user_password)
|
23
|
+
response = request(
|
24
|
+
http_method: :get,
|
25
|
+
endpoint: 'grant/',
|
26
|
+
query_params: {
|
27
|
+
grant_type: 'password',
|
28
|
+
client_id: @api_client_id,
|
29
|
+
client_secret: @api_client_secret,
|
30
|
+
username: user_username,
|
31
|
+
password: user_password
|
32
|
+
},
|
33
|
+
add_access_token: false
|
34
|
+
)
|
35
|
+
res = process_response(response)
|
36
|
+
self.api_access_token = res[:access_token]
|
37
|
+
self.api_refresh_token = res[:refresh_token]
|
38
|
+
return res
|
39
|
+
end
|
40
|
+
|
41
|
+
def renew_token(refresh_token = nil)
|
42
|
+
response = request(
|
43
|
+
http_method: :get,
|
44
|
+
endpoint: 'grant/',
|
45
|
+
query_params: {
|
46
|
+
grant_type: 'refresh_token',
|
47
|
+
client_id: @api_client_id,
|
48
|
+
client_secret: @api_client_secret,
|
49
|
+
refresh_token: refresh_token || @api_refresh_token
|
50
|
+
},
|
51
|
+
add_access_token: false
|
52
|
+
)
|
53
|
+
res = process_response(response)
|
54
|
+
@api_access_token = res[:access_token]
|
55
|
+
return res
|
56
|
+
end
|
57
|
+
|
58
|
+
def companies(other_params: {})
|
59
|
+
response = request(
|
60
|
+
http_method: :get,
|
61
|
+
endpoint: 'companies/getAll/',
|
62
|
+
query_params: other_params
|
63
|
+
)
|
64
|
+
process_response(response)
|
65
|
+
end
|
66
|
+
|
67
|
+
# MoloniApi::Client.new.calendar(38859, '2022-01-01', '2022-07-31')
|
68
|
+
def documents_getAll(company_id, customer_id: nil, your_reference: nil, our_reference: nil, other_params: {})
|
69
|
+
response = request(
|
70
|
+
http_method: :post,
|
71
|
+
endpoint: 'documents/getAll/',
|
72
|
+
params: {
|
73
|
+
company_id: company_id,
|
74
|
+
customer_id: customer_id,
|
75
|
+
your_reference: your_reference,
|
76
|
+
our_reference: our_reference,
|
77
|
+
}.merge(other_params)
|
78
|
+
)
|
79
|
+
process_response(response)
|
80
|
+
end
|
81
|
+
|
82
|
+
def simplifiedInvoices_getAll(company_id, customer_id: nil, your_reference: nil, our_reference: nil, other_params: {})
|
83
|
+
response = request(
|
84
|
+
http_method: :post,
|
85
|
+
endpoint: 'simplifiedInvoices/getAll/',
|
86
|
+
params: {
|
87
|
+
company_id: company_id,
|
88
|
+
customer_id: customer_id,
|
89
|
+
your_reference: your_reference,
|
90
|
+
our_reference: our_reference,
|
91
|
+
}.merge(other_params)
|
92
|
+
)
|
93
|
+
process_response(response)
|
94
|
+
end
|
95
|
+
|
96
|
+
def invoiceReceipts_getAll(company_id, customer_id: nil, your_reference: nil, our_reference: nil, other_params: {})
|
97
|
+
response = request(
|
98
|
+
http_method: :post,
|
99
|
+
endpoint: 'invoiceReceipts/getAll/',
|
100
|
+
params: {
|
101
|
+
company_id: company_id,
|
102
|
+
customer_id: customer_id,
|
103
|
+
your_reference: your_reference,
|
104
|
+
our_reference: our_reference,
|
105
|
+
}.merge(other_params)
|
106
|
+
)
|
107
|
+
process_response(response)
|
108
|
+
end
|
109
|
+
|
110
|
+
# documentSets/getAll
|
111
|
+
def documentSets_getAll(company_id)
|
112
|
+
response = request(
|
113
|
+
http_method: :post,
|
114
|
+
endpoint: 'documentSets/getAll/',
|
115
|
+
params: {
|
116
|
+
company_id: company_id
|
117
|
+
}
|
118
|
+
)
|
119
|
+
process_response(response)
|
120
|
+
end
|
121
|
+
|
122
|
+
# paymentMethods/getAll/
|
123
|
+
def paymentMethods_getAll(company_id)
|
124
|
+
response = request(
|
125
|
+
http_method: :post,
|
126
|
+
endpoint: 'paymentMethods/getAll/',
|
127
|
+
params: {
|
128
|
+
company_id: company_id
|
129
|
+
}
|
130
|
+
)
|
131
|
+
process_response(response)
|
132
|
+
end
|
133
|
+
|
134
|
+
# customers/getAll/
|
135
|
+
def customers_getAll(company_id)
|
136
|
+
response = request(
|
137
|
+
http_method: :post,
|
138
|
+
endpoint: 'customers/getAll/',
|
139
|
+
params: {
|
140
|
+
company_id: company_id
|
141
|
+
}
|
142
|
+
)
|
143
|
+
process_response(response)
|
144
|
+
end
|
145
|
+
|
146
|
+
# customers/insert/
|
147
|
+
def customers_insert(company_id, customer_data: {})
|
148
|
+
# mandatory customer params:
|
149
|
+
# vat, number, name, language_id, address, city, country_id, maturity_date_id, payment_method_id
|
150
|
+
# optional params:
|
151
|
+
# email, zip_code, phone
|
152
|
+
response = request(
|
153
|
+
http_method: :post,
|
154
|
+
endpoint: 'customers/insert/',
|
155
|
+
params: { company_id: company_id }.merge(customer_data)
|
156
|
+
)
|
157
|
+
process_response(response)
|
158
|
+
end
|
159
|
+
|
160
|
+
def invoices_insert(company_id, invoice_params: {}, products: [])
|
161
|
+
# mandatory invoice params:
|
162
|
+
# date, expiration_date, document_set_id, customer_id, products
|
163
|
+
# optional params:
|
164
|
+
# our_reference, your_reference
|
165
|
+
response = request(
|
166
|
+
http_method: :post,
|
167
|
+
endpoint: 'invoices/insert/',
|
168
|
+
params: { company_id: company_id, products: products }.merge(invoice_params)
|
169
|
+
)
|
170
|
+
process_response(response)
|
171
|
+
end
|
172
|
+
|
173
|
+
def simplifiedInvoices_insert(company_id, invoice_params: {}, products: [], payments: [])
|
174
|
+
# mandatory invoice params:
|
175
|
+
# date, expiration_date, document_set_id, customer_id, products, payments
|
176
|
+
# optional params:
|
177
|
+
# our_reference, your_reference...
|
178
|
+
response = request(
|
179
|
+
http_method: :post,
|
180
|
+
endpoint: 'simplifiedInvoices/insert/',
|
181
|
+
params: {
|
182
|
+
company_id: company_id,
|
183
|
+
products: products,
|
184
|
+
payments: payments
|
185
|
+
}.merge(invoice_params)
|
186
|
+
)
|
187
|
+
process_response(response)
|
188
|
+
end
|
189
|
+
|
190
|
+
# invoiceReceipts/insert/
|
191
|
+
def invoiceReceipts_insert(company_id, invoice_params: {}, products: [], payments: [])
|
192
|
+
# mandatory invoice params:
|
193
|
+
# date, expiration_date, document_set_id, customer_id, products, payments
|
194
|
+
# optional params:
|
195
|
+
# our_reference, your_reference...
|
196
|
+
response = request(
|
197
|
+
http_method: :post,
|
198
|
+
endpoint: 'invoiceReceipts/insert/',
|
199
|
+
params: {
|
200
|
+
company_id: company_id,
|
201
|
+
products: products,
|
202
|
+
payments: payments
|
203
|
+
}.merge(invoice_params)
|
204
|
+
)
|
205
|
+
process_response(response)
|
206
|
+
end
|
207
|
+
|
208
|
+
def products_getBySearch(company_id, search_str, other_params: {})
|
209
|
+
response = request(
|
210
|
+
http_method: :post,
|
211
|
+
endpoint: 'products/getBySearch/',
|
212
|
+
params: {
|
213
|
+
company_id: company_id,
|
214
|
+
search: search_str,
|
215
|
+
}.merge(other_params)
|
216
|
+
)
|
217
|
+
process_response(response)
|
218
|
+
end
|
219
|
+
|
220
|
+
def products_getByReference(company_id, reference, other_params: {})
|
221
|
+
response = request(
|
222
|
+
http_method: :post,
|
223
|
+
endpoint: 'products/getByReference/',
|
224
|
+
params: {
|
225
|
+
company_id: company_id,
|
226
|
+
reference: reference,
|
227
|
+
}.merge(other_params)
|
228
|
+
)
|
229
|
+
process_response(response)
|
230
|
+
end
|
231
|
+
|
232
|
+
protected
|
233
|
+
|
234
|
+
def process_response(response)
|
235
|
+
result = response
|
236
|
+
case result
|
237
|
+
when Hash
|
238
|
+
result.transform_keys!(&:to_sym)
|
239
|
+
result.values.each do |r|
|
240
|
+
process_response(r)
|
241
|
+
end
|
242
|
+
when Array
|
243
|
+
result.each do |r|
|
244
|
+
process_response(r)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
result
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'api/config'
|
4
|
+
require_relative 'version'
|
5
|
+
|
6
|
+
module MoloniApi
|
7
|
+
# Stores the configuration
|
8
|
+
class Configuration < API::Config
|
9
|
+
property :follow_redirects, default: true
|
10
|
+
|
11
|
+
# The api endpoint used to connect to MoloniApi if none is set
|
12
|
+
# prd: https://api.moloni.pt/v1/
|
13
|
+
# sandbox: https://api.moloni.pt/sandbox/
|
14
|
+
property :endpoint, default: 'https://api.moloni.pt/sandbox/'
|
15
|
+
|
16
|
+
# The value sent in the http header for 'User-Agent' if none is set
|
17
|
+
property :user_agent, default: "MoloniApi API Ruby Gem #{MoloniApi::VERSION}"
|
18
|
+
|
19
|
+
# By default uses the Faraday connection options if none is set
|
20
|
+
property :connection_options, default: {}
|
21
|
+
|
22
|
+
# By default display 30 resources
|
23
|
+
property :per_page, default: 20
|
24
|
+
|
25
|
+
# Add Faraday::RackBuilder to overwrite middleware
|
26
|
+
property :stack
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoloniApi
|
4
|
+
# Constants
|
5
|
+
module Constants
|
6
|
+
# Response headers
|
7
|
+
RATELIMIT_REMAINING = 'X-RateLimit-Remaining'
|
8
|
+
|
9
|
+
RATELIMIT_LIMIT = 'X-RateLimit-Limit'
|
10
|
+
|
11
|
+
RATELIMIT_RESET = 'X-RateLimit-Reset'
|
12
|
+
|
13
|
+
CONTENT_TYPE = 'Content-Type'
|
14
|
+
|
15
|
+
CONTENT_LENGTH = 'content-length'
|
16
|
+
|
17
|
+
CACHE_CONTROL = 'cache-control'
|
18
|
+
|
19
|
+
ETAG = 'ETag'
|
20
|
+
|
21
|
+
SERVER = 'Server'
|
22
|
+
|
23
|
+
DATE = 'Date'
|
24
|
+
|
25
|
+
LOCATION = 'Location'
|
26
|
+
|
27
|
+
USER_AGENT = 'User-Agent'
|
28
|
+
|
29
|
+
ACCEPT = 'Accept'
|
30
|
+
|
31
|
+
ACCEPT_CHARSET = 'Accept-Charset'
|
32
|
+
|
33
|
+
OAUTH_SCOPES = 'X-OAuth-Scopes'
|
34
|
+
|
35
|
+
ACCEPTED_OAUTH_SCOPES = 'X-Accepted-Oauth-Scopes'
|
36
|
+
|
37
|
+
# Link headers
|
38
|
+
HEADER_LINK = 'Link'
|
39
|
+
|
40
|
+
HEADER_NEXT = 'X-Next'
|
41
|
+
|
42
|
+
HEADER_LAST = 'X-Last'
|
43
|
+
|
44
|
+
META_REL = 'rel'
|
45
|
+
|
46
|
+
META_LAST = 'last'
|
47
|
+
|
48
|
+
META_NEXT = 'next'
|
49
|
+
|
50
|
+
META_FIRST = 'first'
|
51
|
+
|
52
|
+
META_PREV = 'prev'
|
53
|
+
|
54
|
+
PARAM_PAGE = 'page'
|
55
|
+
|
56
|
+
PARAM_PER_PAGE = 'per_page'
|
57
|
+
|
58
|
+
PARAM_START_PAGE = 'start_page'
|
59
|
+
|
60
|
+
PARAM_INCLUDE_RELATED = 'include_related_objects'
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoloniApi
|
4
|
+
module HttpStatusCodes
|
5
|
+
HTTP_OK_CODE = 200
|
6
|
+
|
7
|
+
HTTP_BAD_REQUEST_CODE = 400
|
8
|
+
HTTP_UNAUTHORIZED_CODE = 401
|
9
|
+
HTTP_FORBIDDEN_CODE = 403
|
10
|
+
HTTP_NOT_FOUND_CODE = 404
|
11
|
+
HTTP_UNPROCESSABLE_ENTITY_CODE = 429
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module MoloniApi
|
2
|
+
module Models
|
3
|
+
class Product
|
4
|
+
##
|
5
|
+
# company_id int
|
6
|
+
# Obrigatório
|
7
|
+
#
|
8
|
+
# category_id int
|
9
|
+
# Obrigatório
|
10
|
+
#
|
11
|
+
# type int
|
12
|
+
# Obrigatório
|
13
|
+
#
|
14
|
+
# name string
|
15
|
+
# Obrigatório
|
16
|
+
#
|
17
|
+
# summary string
|
18
|
+
# Facultativo
|
19
|
+
#
|
20
|
+
# reference string
|
21
|
+
# Obrigatório
|
22
|
+
#
|
23
|
+
# ean string
|
24
|
+
# Facultativo
|
25
|
+
#
|
26
|
+
# price float
|
27
|
+
# Obrigatório
|
28
|
+
#
|
29
|
+
# unit_id int
|
30
|
+
# Obrigatório
|
31
|
+
#
|
32
|
+
# has_stock int
|
33
|
+
# Obrigatório
|
34
|
+
#
|
35
|
+
# stock float
|
36
|
+
# Obrigatório
|
37
|
+
#
|
38
|
+
# minimum_stock float
|
39
|
+
# Facultativo
|
40
|
+
#
|
41
|
+
# pos_favorite int
|
42
|
+
# Facultativo
|
43
|
+
#
|
44
|
+
# at_product_category string
|
45
|
+
# Facultativo
|
46
|
+
#
|
47
|
+
# exemption_reason string
|
48
|
+
# Facultativo
|
49
|
+
#
|
50
|
+
# taxes array
|
51
|
+
# Facultativo
|
52
|
+
#
|
53
|
+
# tax_id int
|
54
|
+
# Obrigatório
|
55
|
+
#
|
56
|
+
# value float
|
57
|
+
# Obrigatório
|
58
|
+
#
|
59
|
+
# order int
|
60
|
+
# Obrigatório
|
61
|
+
#
|
62
|
+
# cumulative int
|
63
|
+
# Obrigatório
|
64
|
+
#
|
65
|
+
# suppliers array
|
66
|
+
# Facultativo
|
67
|
+
#
|
68
|
+
# supplier_id int
|
69
|
+
# Obrigatório
|
70
|
+
#
|
71
|
+
# cost_price float
|
72
|
+
# Obrigatório
|
73
|
+
#
|
74
|
+
# referenceint
|
75
|
+
# Facultativo
|
76
|
+
#
|
77
|
+
# properties array
|
78
|
+
# Facultativo
|
79
|
+
#
|
80
|
+
# property_id int
|
81
|
+
# Obrigatório
|
82
|
+
#
|
83
|
+
# value string
|
84
|
+
# Obrigatório
|
85
|
+
#
|
86
|
+
# warehouses array
|
87
|
+
# Facultativo
|
88
|
+
#
|
89
|
+
# warehouse_id int
|
90
|
+
# Obrigatório
|
91
|
+
#
|
92
|
+
# stock float
|
93
|
+
# Obrigatório
|
94
|
+
def initialize(raw_result)
|
95
|
+
@raw_result = raw_result
|
96
|
+
|
97
|
+
@company_id = raw_result[:company_id]
|
98
|
+
@product_id = raw_result[:product_id]
|
99
|
+
@category = raw_result[:category]
|
100
|
+
@type = raw_result[:type]
|
101
|
+
@name = raw_result[:name]
|
102
|
+
@summary = raw_result[:summary]
|
103
|
+
@reference = raw_result[:reference]
|
104
|
+
@ean = raw_result[:ean]
|
105
|
+
@price = raw_result[:price]
|
106
|
+
@unit_id = raw_result[:unit_id]
|
107
|
+
@has_stock = raw_result[:has_stock]
|
108
|
+
@stock = raw_result[:stock]
|
109
|
+
@minimum_stock = raw_result[:minimum_stock]
|
110
|
+
@pos_favorite = raw_result[:pos_favorite]
|
111
|
+
@at_product_category = raw_result[:at_product_category]
|
112
|
+
@exemption_reason = raw_result[:exemption_reason]
|
113
|
+
@taxes = raw_result[:taxes] # array
|
114
|
+
@suppliers = raw_result[:suppliers] # array
|
115
|
+
@properties = raw_result[:properties] # array
|
116
|
+
@warehouses = raw_result[:warehouses] # array
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|