bright 1.2.3 → 2.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 +4 -4
- data/Gemfile +1 -1
- data/Rakefile +0 -1
- data/bright.gemspec +12 -14
- data/lib/bright/address.rb +5 -5
- data/lib/bright/connection.rb +7 -9
- data/lib/bright/contact.rb +7 -9
- data/lib/bright/cursor_response_collection.rb +8 -10
- data/lib/bright/email_address.rb +1 -2
- data/lib/bright/enrollment.rb +2 -2
- data/lib/bright/errors.rb +0 -1
- data/lib/bright/helpers/blank_helper.rb +0 -2
- data/lib/bright/model.rb +13 -13
- data/lib/bright/phone_number.rb +1 -2
- data/lib/bright/response_collection.rb +8 -8
- data/lib/bright/school.rb +1 -4
- data/lib/bright/sis_apis/aeries.rb +25 -26
- data/lib/bright/sis_apis/base.rb +3 -5
- data/lib/bright/sis_apis/bright_sis.rb +82 -84
- data/lib/bright/sis_apis/focus.rb +79 -85
- data/lib/bright/sis_apis/one_roster/infinite_campus.rb +15 -0
- data/lib/bright/sis_apis/one_roster/skyward.rb +6 -0
- data/lib/bright/sis_apis/{infinite_campus.rb → one_roster.rb} +92 -101
- data/lib/bright/sis_apis/power_school.rb +109 -109
- data/lib/bright/sis_apis/synergy.rb +6 -8
- data/lib/bright/sis_apis/tsis.rb +54 -54
- data/lib/bright/student.rb +15 -19
- data/lib/bright/version.rb +1 -1
- data/lib/bright.rb +14 -12
- metadata +6 -5
- data/lib/bright/sis_apis/skyward.rb +0 -276
@@ -1,8 +1,8 @@
|
|
1
1
|
module Bright
|
2
2
|
module SisApi
|
3
3
|
class PowerSchool < Base
|
4
|
-
DATE_FORMAT =
|
5
|
-
INVALID_SEARCH_CHAR_RE = /[
|
4
|
+
DATE_FORMAT = "%Y-%m-%d"
|
5
|
+
INVALID_SEARCH_CHAR_RE = /[,;]/
|
6
6
|
|
7
7
|
@@description = "Connects to the PowerSchool API for accessing student information"
|
8
8
|
@@doc_url = "http://psimages.sunnysideschools.org/api-developer-guide-1.6.0/"
|
@@ -22,30 +22,30 @@ module Bright
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def get_student_by_api_id(api_id, params = {})
|
25
|
-
params =
|
26
|
-
st_hsh =
|
25
|
+
params = apply_expansions(params)
|
26
|
+
st_hsh = request(:get, "ws/v1/student/#{api_id}", params)
|
27
27
|
Student.new(convert_to_student_data(st_hsh["student"])) if st_hsh and st_hsh["student"]
|
28
28
|
end
|
29
29
|
|
30
30
|
def get_student(params = {}, options = {})
|
31
|
-
|
31
|
+
get_students(params, options.merge(per_page: 1, wrap_in_collection: false)).first
|
32
32
|
end
|
33
33
|
|
34
34
|
def get_students(params = {}, options = {})
|
35
|
-
params =
|
36
|
-
params =
|
35
|
+
params = apply_expansions(params)
|
36
|
+
params = apply_options(params, options)
|
37
37
|
|
38
38
|
if options[:wrap_in_collection] != false
|
39
|
-
students_count_response_hash =
|
39
|
+
students_count_response_hash = request(:get, "ws/v1/district/student/count", map_student_search_params(params))
|
40
40
|
# {"resource"=>{"count"=>293}}
|
41
41
|
total_results = students_count_response_hash["resource"]["count"].to_i if students_count_response_hash["resource"]
|
42
42
|
end
|
43
43
|
|
44
|
-
students_response_hash =
|
44
|
+
students_response_hash = request(:get, "ws/v1/district/student", map_student_search_params(params))
|
45
45
|
if students_response_hash and students_response_hash["students"] && students_response_hash["students"]["student"]
|
46
46
|
students_hash = [students_response_hash["students"]["student"]].flatten
|
47
47
|
|
48
|
-
students = students_hash.compact.collect {|st_hsh|
|
48
|
+
students = students_hash.compact.collect { |st_hsh|
|
49
49
|
Student.new(convert_to_student_data(st_hsh))
|
50
50
|
}
|
51
51
|
|
@@ -54,15 +54,15 @@ module Bright
|
|
54
54
|
load_more_call = proc { |page|
|
55
55
|
# pages start at one, so add a page here
|
56
56
|
params[:page] = (page + 1)
|
57
|
-
api.get_students(params, {:
|
57
|
+
api.get_students(params, {wrap_in_collection: false})
|
58
58
|
}
|
59
59
|
|
60
60
|
ResponseCollection.new({
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
61
|
+
seed_page: students,
|
62
|
+
total: total_results,
|
63
|
+
per_page: params[:pagesize],
|
64
|
+
load_more_call: load_more_call,
|
65
|
+
no_threads: options[:no_threads]
|
66
66
|
})
|
67
67
|
else
|
68
68
|
students
|
@@ -73,13 +73,13 @@ module Bright
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def create_student(student, additional_params = {})
|
76
|
-
response =
|
76
|
+
response = request(:post, "ws/v1/student", convert_from_student_data(student, "INSERT", additional_params))
|
77
77
|
if response["results"] and response["results"]["insert_count"] == 1
|
78
78
|
student.api_id = response["results"]["result"]["success_message"]["id"]
|
79
79
|
|
80
80
|
# update our local student object with any data the server might have updated
|
81
|
-
nstudent =
|
82
|
-
student.assign_attributes(
|
81
|
+
nstudent = get_student_by_api_id(student.api_id)
|
82
|
+
student.assign_attributes(Bright::Student.attribute_names.collect { |n| [n, nstudent.send(n)] }.to_h.reject { |k, v| v.nil? })
|
83
83
|
|
84
84
|
# enrollment is no longer needed as creation is over
|
85
85
|
student.enrollment = nil
|
@@ -91,10 +91,10 @@ module Bright
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def update_student(student, additional_params = {})
|
94
|
-
response =
|
94
|
+
response = request(:post, "ws/v1/student", convert_from_student_data(student, "UPDATE", additional_params))
|
95
95
|
if response["results"] and response["results"]["update_count"] == 1
|
96
96
|
student.api_id = response["results"]["result"]["success_message"]["id"]
|
97
|
-
|
97
|
+
get_student_by_api_id(student.api_id)
|
98
98
|
else
|
99
99
|
puts response.inspect
|
100
100
|
student
|
@@ -106,18 +106,18 @@ module Bright
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def get_schools(params = {}, options = {})
|
109
|
-
params =
|
109
|
+
params = apply_options(params, options)
|
110
110
|
|
111
111
|
if options[:wrap_in_collection] != false
|
112
|
-
schools_count_response_hash =
|
112
|
+
schools_count_response_hash = request(:get, "ws/v1/district/school/count", params)
|
113
113
|
# {"resource"=>{"count"=>293}}
|
114
114
|
total_results = schools_count_response_hash["resource"]["count"].to_i if schools_count_response_hash["resource"]
|
115
115
|
end
|
116
116
|
|
117
|
-
schools_response_hash =
|
117
|
+
schools_response_hash = request(:get, "ws/v1/district/school", params)
|
118
118
|
schools_hsh = [schools_response_hash["schools"]["school"]].flatten
|
119
119
|
|
120
|
-
schools = schools_hsh.compact.collect {|st_hsh|
|
120
|
+
schools = schools_hsh.compact.collect { |st_hsh|
|
121
121
|
School.new(convert_to_school_data(st_hsh))
|
122
122
|
}
|
123
123
|
|
@@ -126,15 +126,15 @@ module Bright
|
|
126
126
|
load_more_call = proc { |page|
|
127
127
|
# pages start at one, so add a page here
|
128
128
|
params[:page] = (page + 1)
|
129
|
-
api.get_schools(params, {:
|
129
|
+
api.get_schools(params, {wrap_in_collection: false})
|
130
130
|
}
|
131
131
|
|
132
132
|
ResponseCollection.new({
|
133
|
-
:
|
134
|
-
:
|
135
|
-
:
|
136
|
-
:
|
137
|
-
:
|
133
|
+
seed_page: schools,
|
134
|
+
total: total_results,
|
135
|
+
per_page: params[:pagesize],
|
136
|
+
load_more_call: load_more_call,
|
137
|
+
no_threads: options[:no_threads]
|
138
138
|
})
|
139
139
|
else
|
140
140
|
schools
|
@@ -142,19 +142,19 @@ module Bright
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def retrieve_access_token
|
145
|
-
connection = Bright::Connection.new("#{
|
146
|
-
response = connection.request(:post, "grant_type=client_credentials",
|
145
|
+
connection = Bright::Connection.new("#{connection_options[:uri]}/oauth/access_token/")
|
146
|
+
response = connection.request(:post, "grant_type=client_credentials", headers_for_access_token)
|
147
147
|
if !response.error?
|
148
148
|
response_hash = JSON.parse(response.body)
|
149
149
|
end
|
150
150
|
if response_hash["access_token"]
|
151
|
-
|
151
|
+
connection_options[:access_token] = response_hash["access_token"]
|
152
152
|
end
|
153
153
|
response_hash
|
154
154
|
end
|
155
155
|
|
156
156
|
def request(method, path, params = {})
|
157
|
-
uri
|
157
|
+
uri = "#{connection_options[:uri]}/#{path}"
|
158
158
|
body = nil
|
159
159
|
if method == :get
|
160
160
|
query = URI.encode_www_form(params)
|
@@ -163,10 +163,9 @@ module Bright
|
|
163
163
|
body = JSON.dump(params)
|
164
164
|
end
|
165
165
|
|
166
|
-
|
167
166
|
response = connection_retry_wrapper {
|
168
167
|
connection = Bright::Connection.new(uri)
|
169
|
-
headers =
|
168
|
+
headers = headers_for_auth
|
170
169
|
connection.request(method, body, headers)
|
171
170
|
}
|
172
171
|
|
@@ -186,7 +185,7 @@ module Bright
|
|
186
185
|
default_params = {}
|
187
186
|
|
188
187
|
q = ""
|
189
|
-
%w
|
188
|
+
%w[first_name middle_name last_name].each do |f|
|
190
189
|
if fn = params.delete(f.to_sym)
|
191
190
|
fn = fn.gsub(INVALID_SEARCH_CHAR_RE, " ").strip
|
192
191
|
q += %(name.#{f}==#{fn};)
|
@@ -202,16 +201,16 @@ module Bright
|
|
202
201
|
end
|
203
202
|
params[:q] = q
|
204
203
|
|
205
|
-
default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
|
204
|
+
default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
206
205
|
end
|
207
206
|
|
208
207
|
def convert_to_student_data(attrs)
|
209
208
|
cattrs = {}
|
210
209
|
|
211
210
|
if attrs["name"]
|
212
|
-
cattrs[:first_name]
|
211
|
+
cattrs[:first_name] = attrs["name"]["first_name"]
|
213
212
|
cattrs[:middle_name] = attrs["name"]["middle_name"]
|
214
|
-
cattrs[:last_name]
|
213
|
+
cattrs[:last_name] = attrs["name"]["last_name"]
|
215
214
|
end
|
216
215
|
|
217
216
|
cattrs[:api_id] = attrs["id"].to_s
|
@@ -227,23 +226,24 @@ module Bright
|
|
227
226
|
end
|
228
227
|
end
|
229
228
|
|
230
|
-
|
229
|
+
# To avoid a mismatch of attributes, we'll ignore for now
|
230
|
+
# cattrs[:gender] = attrs["demographics"]["gender"]
|
231
231
|
|
232
232
|
pg = attrs["demographics"]["projected_graduation_year"].to_i
|
233
233
|
cattrs[:projected_graduation_year] = pg if pg > 0
|
234
234
|
end
|
235
235
|
|
236
|
-
#Student Address
|
236
|
+
# Student Address
|
237
237
|
begin
|
238
|
-
cattrs[:addresses] = attrs["addresses"].to_a.collect{|a|
|
238
|
+
cattrs[:addresses] = attrs["addresses"].to_a.collect { |a| convert_to_address_data(a) }.select { |a| !a[:street].blank? }.uniq { |a| a[:street] } if attrs["addresses"]
|
239
239
|
rescue
|
240
240
|
end
|
241
241
|
|
242
|
-
#Ethnicity / Race Info
|
242
|
+
# Ethnicity / Race Info
|
243
243
|
if attrs["ethnicity_race"].is_a?(Hash)
|
244
244
|
if !(race_hshs = attrs.dig("ethnicity_race", "races")).nil?
|
245
|
-
#this should be an array, but it doesn't appear PS always sends it as one
|
246
|
-
cattrs[:race] = [race_hshs].flatten.map{|race_hsh| race_hsh["district_race_code"]}.compact.uniq
|
245
|
+
# this should be an array, but it doesn't appear PS always sends it as one
|
246
|
+
cattrs[:race] = [race_hshs].flatten.map { |race_hsh| race_hsh["district_race_code"] }.compact.uniq
|
247
247
|
end
|
248
248
|
|
249
249
|
if !attrs.dig("ethnicity_race", "federal_ethnicity").nil?
|
@@ -254,16 +254,16 @@ module Bright
|
|
254
254
|
end
|
255
255
|
end
|
256
256
|
|
257
|
-
#Contacts Info
|
258
|
-
[1,2].each do |contact_id|
|
257
|
+
# Contacts Info
|
258
|
+
[1, 2].each do |contact_id|
|
259
259
|
if !attrs.dig("contact", "emergency_contact_name#{contact_id}").blank? and !attrs.dig("contact", "emergency_phone#{contact_id}").blank?
|
260
260
|
cattrs[:contacts] ||= []
|
261
261
|
contact_attrs = {
|
262
|
-
:
|
263
|
-
:
|
264
|
-
:
|
262
|
+
first_name: attrs.dig("contact", "emergency_contact_name#{contact_id}").to_s.split(",").last.strip,
|
263
|
+
last_name: attrs.dig("contact", "emergency_contact_name#{contact_id}").to_s.split(",").first.strip,
|
264
|
+
phone_numbers: [
|
265
265
|
{
|
266
|
-
:
|
266
|
+
phone_number: attrs.dig("contact", "emergency_phone#{contact_id}")
|
267
267
|
}
|
268
268
|
]
|
269
269
|
}
|
@@ -271,67 +271,67 @@ module Bright
|
|
271
271
|
end
|
272
272
|
end
|
273
273
|
|
274
|
-
cattrs.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
|
274
|
+
cattrs.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
275
275
|
end
|
276
276
|
|
277
277
|
def convert_from_student_data(student, action = nil, additional_params = {})
|
278
278
|
return {} if student.nil?
|
279
279
|
|
280
280
|
student_data = {
|
281
|
-
:
|
282
|
-
:
|
283
|
-
:
|
284
|
-
:
|
285
|
-
:
|
286
|
-
:
|
287
|
-
:
|
288
|
-
:
|
289
|
-
:
|
290
|
-
}.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?},
|
291
|
-
:
|
292
|
-
|
293
|
-
:
|
294
|
-
:
|
295
|
-
|
296
|
-
|
281
|
+
client_uid: student.client_id,
|
282
|
+
action: action,
|
283
|
+
id: student.api_id,
|
284
|
+
local_id: student.sis_student_id,
|
285
|
+
state_province_id: student.state_student_id,
|
286
|
+
name: {
|
287
|
+
first_name: student.first_name,
|
288
|
+
middle_name: student.middle_name,
|
289
|
+
last_name: student.last_name
|
290
|
+
}.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? },
|
291
|
+
demographics: {
|
292
|
+
# To avoid a mismatch of attributes, we'll ignore for now
|
293
|
+
# :gender => student.gender.to_s[0].to_s.upcase,
|
294
|
+
birth_date: (student.birth_date ? student.birth_date.strftime(DATE_FORMAT) : nil),
|
295
|
+
projected_graduation_year: student.projected_graduation_year
|
296
|
+
}.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
297
|
+
}.merge(additional_params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
297
298
|
|
298
299
|
# apply enrollment info
|
299
300
|
if student.enrollment
|
300
|
-
student_data.merge!(
|
301
|
+
student_data.merge!(convert_from_enrollment_data(student.enrollment))
|
301
302
|
end
|
302
303
|
|
303
304
|
# apply addresses
|
304
305
|
address_data = {}
|
305
|
-
if ph = student.addresses.detect{|a| a.type == "physical"}
|
306
|
-
address_data.merge!(
|
306
|
+
if ph = student.addresses.detect { |a| a.type == "physical" }
|
307
|
+
address_data.merge!(convert_from_address_data(ph))
|
307
308
|
end
|
308
|
-
if mail = student.addresses.detect{|a| a.type == "mailing"}
|
309
|
-
address_data.merge!(
|
309
|
+
if mail = student.addresses.detect { |a| a.type == "mailing" }
|
310
|
+
address_data.merge!(convert_from_address_data(mail))
|
310
311
|
end
|
311
312
|
if ph.nil? and mail.nil? and any = student.addresses.first
|
312
313
|
cany = any.clone
|
313
314
|
cany.type = "physical"
|
314
|
-
address_data.merge!(
|
315
|
+
address_data.merge!(convert_from_address_data(cany))
|
315
316
|
end
|
316
317
|
if address_data.size > 0
|
317
|
-
student_data.merge!({:
|
318
|
+
student_data.merge!({addresses: address_data})
|
318
319
|
end
|
319
320
|
|
320
|
-
{:
|
321
|
+
{students: {student: student_data}}
|
321
322
|
end
|
322
323
|
|
323
324
|
def convert_from_enrollment_data(enrollment)
|
324
325
|
return {} if enrollment.nil?
|
325
|
-
{:
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
}
|
326
|
+
{school_enrollment: {
|
327
|
+
enroll_status: "A",
|
328
|
+
entry_date: (enrollment.entry_date || Date.today).strftime(DATE_FORMAT),
|
329
|
+
entry_comment: enrollment.entry_comment,
|
330
|
+
exit_date: (enrollment.exit_date || enrollment.entry_date || Date.today).strftime(DATE_FORMAT),
|
331
|
+
exit_comment: enrollment.exit_comment,
|
332
|
+
grade_level: enrollment.grade,
|
333
|
+
school_number: enrollment.school ? enrollment.school.number : nil
|
334
|
+
}.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }}
|
335
335
|
end
|
336
336
|
|
337
337
|
def convert_to_school_data(attrs)
|
@@ -345,21 +345,21 @@ module Bright
|
|
345
345
|
cattrs[:address] = convert_to_address_data(address_attributes)
|
346
346
|
end
|
347
347
|
if (phone_number_attributes = attrs.dig("phones", "main", "number"))
|
348
|
-
cattrs[:phone_number] = {:
|
348
|
+
cattrs[:phone_number] = {phone_number: phone_number_attributes}
|
349
349
|
end
|
350
350
|
|
351
|
-
cattrs.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
|
351
|
+
cattrs.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
352
352
|
end
|
353
353
|
|
354
354
|
def convert_from_address_data(address)
|
355
355
|
{
|
356
|
-
|
357
|
-
:
|
358
|
-
:
|
359
|
-
:
|
360
|
-
:
|
361
|
-
:
|
362
|
-
}.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
|
356
|
+
address.type || "physcial" => {
|
357
|
+
street: "#{address.street} #{address.apt}", # powerschool doesn't appear to support passing the apt in the api
|
358
|
+
city: address.city,
|
359
|
+
state_province: address.state,
|
360
|
+
postal_code: address.postal_code,
|
361
|
+
grid_location: address.geographical_coordinates.to_s.gsub(",", ", ") # make sure there is a comma + space
|
362
|
+
}.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
363
363
|
}
|
364
364
|
end
|
365
365
|
|
@@ -386,24 +386,24 @@ module Bright
|
|
386
386
|
cattrs[:latitude], cattrs[:longitude] = lat_lng
|
387
387
|
end
|
388
388
|
|
389
|
-
cattrs.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
|
389
|
+
cattrs.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
390
390
|
end
|
391
391
|
|
392
392
|
def apply_expansions(params)
|
393
|
-
if
|
394
|
-
hsh =
|
393
|
+
if expansion_options.empty?
|
394
|
+
hsh = request(:get, "ws/v1/district/student", {pagesize: 1, q: "local_id==0"})
|
395
395
|
if hsh and hsh["students"]
|
396
396
|
self.expansion_options = {
|
397
|
-
:
|
398
|
-
:
|
397
|
+
expansions: hsh["students"]["@expansions"].to_s.split(/,\s?/),
|
398
|
+
extensions: hsh["students"]["@extensions"].to_s.split(/,\s?/)
|
399
399
|
}
|
400
400
|
end
|
401
401
|
end
|
402
402
|
|
403
403
|
params.merge({
|
404
|
-
:
|
405
|
-
:
|
406
|
-
}.reject{|k,v| v.empty?})
|
404
|
+
expansions: (%w[demographics addresses ethnicity_race phones contact contact_info] & (expansion_options[:expansions] || [])).join(","),
|
405
|
+
extensions: (%w[studentcorefields] & (expansion_options[:extensions] || [])).join(",")
|
406
|
+
}.reject { |k, v| v.empty? })
|
407
407
|
end
|
408
408
|
|
409
409
|
def apply_options(params, options)
|
@@ -414,17 +414,17 @@ module Bright
|
|
414
414
|
|
415
415
|
def headers_for_access_token
|
416
416
|
{
|
417
|
-
"Authorization" => "Basic #{Base64.strict_encode64("#{
|
417
|
+
"Authorization" => "Basic #{Base64.strict_encode64("#{connection_options[:client_id]}:#{connection_options[:client_secret]}")}",
|
418
418
|
"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
|
419
419
|
}
|
420
420
|
end
|
421
421
|
|
422
422
|
def headers_for_auth
|
423
|
-
|
423
|
+
retrieve_access_token if connection_options[:access_token].nil?
|
424
424
|
{
|
425
|
-
"Authorization" => "Bearer #{
|
425
|
+
"Authorization" => "Bearer #{connection_options[:access_token]}",
|
426
426
|
"Accept" => "application/json;charset=UTF-8",
|
427
|
-
"Content-Type" =>"application/json;charset=UTF-8"
|
427
|
+
"Content-Type" => "application/json;charset=UTF-8"
|
428
428
|
}
|
429
429
|
end
|
430
430
|
end
|
@@ -1,31 +1,29 @@
|
|
1
1
|
module Bright
|
2
2
|
module SisApi
|
3
3
|
class Synergy < Base
|
4
|
-
|
5
4
|
def get_student_by_api_id(api_id)
|
6
5
|
raise NotImplementedError
|
7
6
|
end
|
8
|
-
|
7
|
+
|
9
8
|
def get_student(params)
|
10
9
|
raise NotImplementedError
|
11
10
|
end
|
12
|
-
|
11
|
+
|
13
12
|
def get_students(params)
|
14
13
|
raise NotImplementedError
|
15
14
|
end
|
16
|
-
|
15
|
+
|
17
16
|
def create_student(student)
|
18
17
|
raise NotImplementedError
|
19
18
|
end
|
20
|
-
|
19
|
+
|
21
20
|
def update_student(student)
|
22
21
|
raise NotImplementedError
|
23
22
|
end
|
24
|
-
|
23
|
+
|
25
24
|
def get_schools(params)
|
26
25
|
raise NotImplementedError
|
27
26
|
end
|
28
|
-
|
29
27
|
end
|
30
28
|
end
|
31
|
-
end
|
29
|
+
end
|