ecoportal-api 0.8.5 → 0.9.2
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 +4 -4
- data/.gitignore +20 -20
- data/.rspec +3 -3
- data/.rubocop.yml +55 -55
- data/.travis.yml +5 -5
- data/.yardopts +10 -10
- data/CHANGELOG.md +257 -236
- data/Gemfile +6 -6
- data/LICENSE +21 -21
- data/README.md +34 -34
- data/Rakefile +27 -27
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/ecoportal-api.gemspec +36 -36
- data/lib/ecoportal/api/common/base_class.rb +33 -29
- data/lib/ecoportal/api/common/base_model.rb +195 -177
- data/lib/ecoportal/api/common/batch_operation.rb +119 -119
- data/lib/ecoportal/api/common/batch_response.rb +34 -34
- data/lib/ecoportal/api/common/client.rb +198 -196
- data/lib/ecoportal/api/common/doc_helpers.rb +29 -29
- data/lib/ecoportal/api/common/elastic_apm_integration.rb +112 -112
- data/lib/ecoportal/api/common/hash_diff.rb +41 -41
- data/lib/ecoportal/api/common/logging.rb +12 -12
- data/lib/ecoportal/api/common/response.rb +31 -31
- data/lib/ecoportal/api/common/wrapped_response.rb +54 -54
- data/lib/ecoportal/api/common.rb +18 -18
- data/lib/ecoportal/api/errors/base.rb +8 -8
- data/lib/ecoportal/api/errors/time_out.rb +8 -8
- data/lib/ecoportal/api/errors.rb +9 -9
- data/lib/ecoportal/api/internal/account.rb +99 -100
- data/lib/ecoportal/api/internal/login_provider.rb +9 -9
- data/lib/ecoportal/api/internal/login_providers.rb +33 -33
- data/lib/ecoportal/api/internal/people.rb +14 -14
- data/lib/ecoportal/api/internal/permissions.rb +14 -13
- data/lib/ecoportal/api/internal/person.rb +101 -53
- data/lib/ecoportal/api/internal/person_details.rb +9 -9
- data/lib/ecoportal/api/internal/person_schema.rb +10 -10
- data/lib/ecoportal/api/internal/person_schemas.rb +11 -11
- data/lib/ecoportal/api/internal/policy_group.rb +9 -9
- data/lib/ecoportal/api/internal/policy_groups.rb +32 -32
- data/lib/ecoportal/api/internal/preferences.rb +31 -31
- data/lib/ecoportal/api/internal/schema_field.rb +8 -8
- data/lib/ecoportal/api/internal/schema_field_value.rb +8 -8
- data/lib/ecoportal/api/internal.rb +31 -31
- data/lib/ecoportal/api/logger.rb +62 -62
- data/lib/ecoportal/api/v1/people.rb +218 -218
- data/lib/ecoportal/api/v1/person.rb +138 -135
- data/lib/ecoportal/api/v1/person_details.rb +94 -82
- data/lib/ecoportal/api/v1/person_schema.rb +53 -53
- data/lib/ecoportal/api/v1/person_schemas.rb +48 -48
- data/lib/ecoportal/api/v1/schema_field.rb +34 -34
- data/lib/ecoportal/api/v1/schema_field_value.rb +65 -65
- data/lib/ecoportal/api/v1.rb +49 -49
- data/lib/ecoportal/api/version.rb +5 -5
- data/lib/ecoportal/api.rb +16 -16
- metadata +3 -3
@@ -1,218 +1,218 @@
|
|
1
|
-
module Ecoportal
|
2
|
-
module API
|
3
|
-
class V1
|
4
|
-
# @attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
|
5
|
-
class People
|
6
|
-
extend Common::BaseClass
|
7
|
-
include Enumerable
|
8
|
-
include Common::DocHelpers
|
9
|
-
|
10
|
-
JOB_TIMEOUT = 240
|
11
|
-
DELAY_STATUS_CHECK = 5
|
12
|
-
|
13
|
-
class_resolver :person_class, "Ecoportal::API::V1::Person"
|
14
|
-
|
15
|
-
attr_reader :client
|
16
|
-
|
17
|
-
# @param client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
|
18
|
-
# @return [People] an instance object ready to make people api requests.
|
19
|
-
def initialize(client)
|
20
|
-
@client = client
|
21
|
-
end
|
22
|
-
|
23
|
-
# Iterates all the people of the organization.
|
24
|
-
# @note
|
25
|
-
# - it ignores the key `cursor_id:` of `params:`.
|
26
|
-
# - `each` is called by `to_a`
|
27
|
-
# @param params [Hash]
|
28
|
-
# @option params [String] :per_page the number of people you get per request.
|
29
|
-
# @option params [String] :q some text to search. Omit this parameter to target all the people.
|
30
|
-
# @param silent [Boolean] `false` to show percentage of progress.
|
31
|
-
# @yield [person] does some stuff with the person.
|
32
|
-
# @yieldparam person [Person]
|
33
|
-
def each(params: {}, silent: false, &block)
|
34
|
-
return to_enum(:each, params: params, silent: silent) unless block
|
35
|
-
cursor_id = nil; results = 0
|
36
|
-
puts "\n" unless silent
|
37
|
-
loop do
|
38
|
-
params.update(cursor_id: cursor_id) if cursor_id
|
39
|
-
body = nil; response = nil; count = 5
|
40
|
-
loop do
|
41
|
-
response = client.get("/people", params: params)
|
42
|
-
body = response && body_data(response.body)
|
43
|
-
break if response.success? || count <= 0
|
44
|
-
puts "Request failed - Status #{response.status}: #{body}"
|
45
|
-
count -= 1
|
46
|
-
sleep(0.5)
|
47
|
-
end
|
48
|
-
raise "Request failed - Status #{response.status}: #{body}" unless response.success?
|
49
|
-
|
50
|
-
unless silent || (total = body["total_results"]) == 0
|
51
|
-
results += body["results"].length
|
52
|
-
percent = results * 100 / total
|
53
|
-
msg = "People GET"
|
54
|
-
msg += " (search=#{params[:q]})" if params.key?(:q)
|
55
|
-
print "#{msg}: #{percent.round}% (of #{total})\r"
|
56
|
-
$stdout.flush
|
57
|
-
end
|
58
|
-
|
59
|
-
body["results"].each do |person|
|
60
|
-
yield person_class.new(person)
|
61
|
-
end
|
62
|
-
break unless (cursor_id = body["cursor_id"])
|
63
|
-
end
|
64
|
-
self
|
65
|
-
end
|
66
|
-
|
67
|
-
# Gets all the people via api requests.
|
68
|
-
# @note it ignores the key `:cursor_id` in `params:`.
|
69
|
-
# @param params [Hash]
|
70
|
-
# @option params [Integer] :per_page the number of people you get per request.
|
71
|
-
# @option params [String] :q some text to search.
|
72
|
-
# @param silent [Boolean] `false` to show percentage of progress.
|
73
|
-
# @return [Array<Person>] the array of people got via api.
|
74
|
-
def get_all(params: {}, silent: false)
|
75
|
-
each(params: params, silent: silent).to_a
|
76
|
-
end
|
77
|
-
|
78
|
-
# Gets a person via api.
|
79
|
-
# @note if the request has `success?` the returned `object.result` gives an object with that `Person`.
|
80
|
-
# @param doc [String, Hash, Person] data containing an `id` (internal or external) of the target person.
|
81
|
-
# @return [Person] the person with `id` (internal or external) contained in `doc`.
|
82
|
-
def get(doc)
|
83
|
-
id = get_id(doc)
|
84
|
-
response = client.get("/people/"+CGI.escape(id))
|
85
|
-
body = body_data(response.body)
|
86
|
-
return person_class.new(body) if response.success?
|
87
|
-
raise "Could not get person #{id} - Error #{response.status}: #{body}"
|
88
|
-
end
|
89
|
-
|
90
|
-
# Requests an update of a person via api.
|
91
|
-
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
92
|
-
# @return [Response] an object with the api response.
|
93
|
-
def update(doc)
|
94
|
-
body = get_body(doc)
|
95
|
-
id = get_id(doc)
|
96
|
-
client.patch("/people/"+CGI.escape(id), data: body)
|
97
|
-
end
|
98
|
-
|
99
|
-
# Requests to create a person via api.
|
100
|
-
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
101
|
-
# @return [Response] an object with the api response.
|
102
|
-
def create(doc)
|
103
|
-
body = get_body(doc)
|
104
|
-
client.post("/people", data: body)
|
105
|
-
end
|
106
|
-
|
107
|
-
# Requests to update an existing person or if it does not exist, to create it, via api.
|
108
|
-
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
109
|
-
# @return [Response] an object with the api response.
|
110
|
-
def upsert(doc)
|
111
|
-
body = get_body(doc)
|
112
|
-
id = get_id(doc)
|
113
|
-
client.post("/people/"+CGI.escape(id), data: body)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Requests to completelly remove from an organization an existing person via api.
|
117
|
-
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
118
|
-
# @return [Response] an object with the api response.
|
119
|
-
def delete(doc)
|
120
|
-
id = get_id(doc)
|
121
|
-
client.delete("/people/"+CGI.escape(id))
|
122
|
-
end
|
123
|
-
|
124
|
-
# Creates a `BatchOperation` and yields it to the given bock.
|
125
|
-
# @yield [batch_op] adds multiple api requests for the current batch.
|
126
|
-
# @yieldparam batch_op [BatchOperation]
|
127
|
-
# @param job_mode [Boolean] whether or not it should use batch jobs
|
128
|
-
# @return [Ecoportal::API::Common::Response] the results of the batch
|
129
|
-
def batch(job_mode: true, &block)
|
130
|
-
return job(&block) if job_mode
|
131
|
-
operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
|
132
|
-
yield operation
|
133
|
-
# The batch operation is responsible for logging the output
|
134
|
-
client.post("/people/batch", data: operation.as_json).tap do |response|
|
135
|
-
operation.process_response(response)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# @return [Ecoportal::API::Common::Response] the results of the batch job
|
140
|
-
def job
|
141
|
-
operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
|
142
|
-
yield operation
|
143
|
-
job_id = create_job(operation)
|
144
|
-
status = wait_for_job_completion(job_id)
|
145
|
-
|
146
|
-
if status&.complete?
|
147
|
-
job_result(job_id, operation)
|
148
|
-
else
|
149
|
-
msg = "Job `#{job_id}` not complete. Probably timeout after #{JOB_TIMEOUT} seconds. Current status: #{status}"
|
150
|
-
raise API::Errors::TimeOut.new msg
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
# Creates a new `Person` object.
|
155
|
-
# @return [Person] new empty person object of the current version.
|
156
|
-
def new
|
157
|
-
person_class.new
|
158
|
-
end
|
159
|
-
|
160
|
-
private
|
161
|
-
|
162
|
-
JobStatus = Struct.new(:id, :complete?, :errored?, :progress)
|
163
|
-
def job_status(job_id)
|
164
|
-
response = client.get("/people/job/#{CGI.escape(job_id)}/status")
|
165
|
-
body = response && body_data(response.body)
|
166
|
-
raise "Status error (#{response.status}) - Errors: #{body}" unless response.success?
|
167
|
-
JobStatus.new(
|
168
|
-
body["id"],
|
169
|
-
body["complete"],
|
170
|
-
body["errored"],
|
171
|
-
body["progress"]
|
172
|
-
)
|
173
|
-
end
|
174
|
-
|
175
|
-
# @return [Ecoportal::API::Common::Response] the results of the batch job
|
176
|
-
def job_result(job_id, operation)
|
177
|
-
client.get("/people/job/#{CGI.escape(job_id)}").tap do |response|
|
178
|
-
operation.process_response(response)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def wait_for_job_completion(job_id)
|
183
|
-
# timeout library is evil. So we make poor-man timeout.
|
184
|
-
# https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
|
185
|
-
before = Time.now
|
186
|
-
while true
|
187
|
-
status = job_status(job_id)
|
188
|
-
break status if status.complete?
|
189
|
-
break status if Time.now >= before + JOB_TIMEOUT
|
190
|
-
sleep(DELAY_STATUS_CHECK)
|
191
|
-
status
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
# @return [String] the `id` of the created batch job
|
196
|
-
def create_job(operation)
|
197
|
-
job_id = nil
|
198
|
-
client.post("/people/job", data: operation.as_json).tap do |response|
|
199
|
-
job_id = body_data(response.body)["id"] if response.success?
|
200
|
-
raise "Could not create job - Error (#{response.status}): #{body_data(response.body)}" unless job_id
|
201
|
-
end
|
202
|
-
job_id
|
203
|
-
end
|
204
|
-
|
205
|
-
# Hook for other api versions to obtain the raw data of a response
|
206
|
-
# @note this was introduced to allow `v2` to reuse this class
|
207
|
-
def body_data(body)
|
208
|
-
body
|
209
|
-
end
|
210
|
-
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
require 'ecoportal/api/v1/schema_field_value'
|
217
|
-
require 'ecoportal/api/v1/person_details'
|
218
|
-
require 'ecoportal/api/v1/person'
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
class V1
|
4
|
+
# @attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
|
5
|
+
class People
|
6
|
+
extend Common::BaseClass
|
7
|
+
include Enumerable
|
8
|
+
include Common::DocHelpers
|
9
|
+
|
10
|
+
JOB_TIMEOUT = 240
|
11
|
+
DELAY_STATUS_CHECK = 5
|
12
|
+
|
13
|
+
class_resolver :person_class, "Ecoportal::API::V1::Person"
|
14
|
+
|
15
|
+
attr_reader :client
|
16
|
+
|
17
|
+
# @param client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
|
18
|
+
# @return [People] an instance object ready to make people api requests.
|
19
|
+
def initialize(client)
|
20
|
+
@client = client
|
21
|
+
end
|
22
|
+
|
23
|
+
# Iterates all the people of the organization.
|
24
|
+
# @note
|
25
|
+
# - it ignores the key `cursor_id:` of `params:`.
|
26
|
+
# - `each` is called by `to_a`
|
27
|
+
# @param params [Hash]
|
28
|
+
# @option params [String] :per_page the number of people you get per request.
|
29
|
+
# @option params [String] :q some text to search. Omit this parameter to target all the people.
|
30
|
+
# @param silent [Boolean] `false` to show percentage of progress.
|
31
|
+
# @yield [person] does some stuff with the person.
|
32
|
+
# @yieldparam person [Person]
|
33
|
+
def each(params: {}, silent: false, &block)
|
34
|
+
return to_enum(:each, params: params, silent: silent) unless block
|
35
|
+
cursor_id = nil; results = 0
|
36
|
+
puts "\n" unless silent
|
37
|
+
loop do
|
38
|
+
params.update(cursor_id: cursor_id) if cursor_id
|
39
|
+
body = nil; response = nil; count = 5
|
40
|
+
loop do
|
41
|
+
response = client.get("/people", params: params)
|
42
|
+
body = response && body_data(response.body)
|
43
|
+
break if response.success? || count <= 0
|
44
|
+
puts "Request failed - Status #{response.status}: #{body}"
|
45
|
+
count -= 1
|
46
|
+
sleep(0.5)
|
47
|
+
end
|
48
|
+
raise "Request failed - Status #{response.status}: #{body}" unless response.success?
|
49
|
+
|
50
|
+
unless silent || (total = body["total_results"]) == 0
|
51
|
+
results += body["results"].length
|
52
|
+
percent = results * 100 / total
|
53
|
+
msg = "People GET"
|
54
|
+
msg += " (search=#{params[:q]})" if params.key?(:q)
|
55
|
+
print "#{msg}: #{percent.round}% (of #{total})\r"
|
56
|
+
$stdout.flush
|
57
|
+
end
|
58
|
+
|
59
|
+
body["results"].each do |person|
|
60
|
+
yield person_class.new(person)
|
61
|
+
end
|
62
|
+
break unless (cursor_id = body["cursor_id"])
|
63
|
+
end
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
# Gets all the people via api requests.
|
68
|
+
# @note it ignores the key `:cursor_id` in `params:`.
|
69
|
+
# @param params [Hash]
|
70
|
+
# @option params [Integer] :per_page the number of people you get per request.
|
71
|
+
# @option params [String] :q some text to search.
|
72
|
+
# @param silent [Boolean] `false` to show percentage of progress.
|
73
|
+
# @return [Array<Person>] the array of people got via api.
|
74
|
+
def get_all(params: {}, silent: false)
|
75
|
+
each(params: params, silent: silent).to_a
|
76
|
+
end
|
77
|
+
|
78
|
+
# Gets a person via api.
|
79
|
+
# @note if the request has `success?` the returned `object.result` gives an object with that `Person`.
|
80
|
+
# @param doc [String, Hash, Person] data containing an `id` (internal or external) of the target person.
|
81
|
+
# @return [Person] the person with `id` (internal or external) contained in `doc`.
|
82
|
+
def get(doc)
|
83
|
+
id = get_id(doc)
|
84
|
+
response = client.get("/people/"+CGI.escape(id))
|
85
|
+
body = body_data(response.body)
|
86
|
+
return person_class.new(body) if response.success?
|
87
|
+
raise "Could not get person #{id} - Error #{response.status}: #{body}"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Requests an update of a person via api.
|
91
|
+
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
92
|
+
# @return [Response] an object with the api response.
|
93
|
+
def update(doc)
|
94
|
+
body = get_body(doc)
|
95
|
+
id = get_id(doc)
|
96
|
+
client.patch("/people/"+CGI.escape(id), data: body)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Requests to create a person via api.
|
100
|
+
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
101
|
+
# @return [Response] an object with the api response.
|
102
|
+
def create(doc)
|
103
|
+
body = get_body(doc)
|
104
|
+
client.post("/people", data: body)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Requests to update an existing person or if it does not exist, to create it, via api.
|
108
|
+
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
109
|
+
# @return [Response] an object with the api response.
|
110
|
+
def upsert(doc)
|
111
|
+
body = get_body(doc)
|
112
|
+
id = get_id(doc)
|
113
|
+
client.post("/people/"+CGI.escape(id), data: body)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Requests to completelly remove from an organization an existing person via api.
|
117
|
+
# @param doc [Person, Hash] data that at least contains an `id` (internal or external) of the target person.
|
118
|
+
# @return [Response] an object with the api response.
|
119
|
+
def delete(doc)
|
120
|
+
id = get_id(doc)
|
121
|
+
client.delete("/people/"+CGI.escape(id))
|
122
|
+
end
|
123
|
+
|
124
|
+
# Creates a `BatchOperation` and yields it to the given bock.
|
125
|
+
# @yield [batch_op] adds multiple api requests for the current batch.
|
126
|
+
# @yieldparam batch_op [BatchOperation]
|
127
|
+
# @param job_mode [Boolean] whether or not it should use batch jobs
|
128
|
+
# @return [Ecoportal::API::Common::Response] the results of the batch
|
129
|
+
def batch(job_mode: true, &block)
|
130
|
+
return job(&block) if job_mode
|
131
|
+
operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
|
132
|
+
yield operation
|
133
|
+
# The batch operation is responsible for logging the output
|
134
|
+
client.post("/people/batch", data: operation.as_json).tap do |response|
|
135
|
+
operation.process_response(response)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# @return [Ecoportal::API::Common::Response] the results of the batch job
|
140
|
+
def job
|
141
|
+
operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
|
142
|
+
yield operation
|
143
|
+
job_id = create_job(operation)
|
144
|
+
status = wait_for_job_completion(job_id)
|
145
|
+
|
146
|
+
if status&.complete?
|
147
|
+
job_result(job_id, operation)
|
148
|
+
else
|
149
|
+
msg = "Job `#{job_id}` not complete. Probably timeout after #{JOB_TIMEOUT} seconds. Current status: #{status}"
|
150
|
+
raise API::Errors::TimeOut.new msg
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Creates a new `Person` object.
|
155
|
+
# @return [Person] new empty person object of the current version.
|
156
|
+
def new
|
157
|
+
person_class.new
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
JobStatus = Struct.new(:id, :complete?, :errored?, :progress)
|
163
|
+
def job_status(job_id)
|
164
|
+
response = client.get("/people/job/#{CGI.escape(job_id)}/status")
|
165
|
+
body = response && body_data(response.body)
|
166
|
+
raise "Status error (#{response.status}) - Errors: #{body}" unless response.success?
|
167
|
+
JobStatus.new(
|
168
|
+
body["id"],
|
169
|
+
body["complete"],
|
170
|
+
body["errored"],
|
171
|
+
body["progress"]
|
172
|
+
)
|
173
|
+
end
|
174
|
+
|
175
|
+
# @return [Ecoportal::API::Common::Response] the results of the batch job
|
176
|
+
def job_result(job_id, operation)
|
177
|
+
client.get("/people/job/#{CGI.escape(job_id)}").tap do |response|
|
178
|
+
operation.process_response(response)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def wait_for_job_completion(job_id)
|
183
|
+
# timeout library is evil. So we make poor-man timeout.
|
184
|
+
# https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
|
185
|
+
before = Time.now
|
186
|
+
while true
|
187
|
+
status = job_status(job_id)
|
188
|
+
break status if status.complete?
|
189
|
+
break status if Time.now >= before + JOB_TIMEOUT
|
190
|
+
sleep(DELAY_STATUS_CHECK)
|
191
|
+
status
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# @return [String] the `id` of the created batch job
|
196
|
+
def create_job(operation)
|
197
|
+
job_id = nil
|
198
|
+
client.post("/people/job", data: operation.as_json).tap do |response|
|
199
|
+
job_id = body_data(response.body)["id"] if response.success?
|
200
|
+
raise "Could not create job - Error (#{response.status}): #{body_data(response.body)}" unless job_id
|
201
|
+
end
|
202
|
+
job_id
|
203
|
+
end
|
204
|
+
|
205
|
+
# Hook for other api versions to obtain the raw data of a response
|
206
|
+
# @note this was introduced to allow `v2` to reuse this class
|
207
|
+
def body_data(body)
|
208
|
+
body
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
require 'ecoportal/api/v1/schema_field_value'
|
217
|
+
require 'ecoportal/api/v1/person_details'
|
218
|
+
require 'ecoportal/api/v1/person'
|