moloni_api 0.1.0
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/.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
|