osm 0.1.17 → 0.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.
- data/CHANGELOG.md +45 -0
- data/Guardfile +9 -0
- data/README.md +15 -13
- data/lib/osm.rb +14 -0
- data/lib/osm/activity.rb +44 -13
- data/lib/osm/api.rb +48 -12
- data/lib/osm/api_access.rb +9 -6
- data/lib/osm/due_badges.rb +5 -4
- data/lib/osm/event.rb +87 -107
- data/lib/osm/flexi_record.rb +159 -118
- data/lib/osm/grouping.rb +41 -2
- data/lib/osm/{evening.rb → meeting.rb} +71 -64
- data/lib/osm/member.rb +88 -68
- data/lib/osm/model.rb +120 -30
- data/lib/osm/register.rb +23 -14
- data/lib/osm/section.rb +40 -100
- data/lib/osm/term.rb +35 -24
- data/osm.gemspec +2 -0
- data/spec/osm/activity_spec.rb +190 -173
- data/spec/osm/api_access_spec.rb +15 -7
- data/spec/osm/api_spec.rb +54 -27
- data/spec/osm/event_spec.rb +95 -84
- data/spec/osm/flexi_record_spec.rb +138 -35
- data/spec/osm/grouping_spec.rb +59 -1
- data/spec/osm/{evening_spec.rb → meeting_spec.rb} +53 -53
- data/spec/osm/member_spec.rb +151 -45
- data/spec/osm/model_spec.rb +28 -34
- data/spec/osm/register_spec.rb +1 -1
- data/spec/osm/section_spec.rb +49 -82
- data/spec/osm/term_spec.rb +23 -15
- data/spec/spec_helper.rb +25 -0
- data/version.rb +1 -1
- metadata +41 -18
data/lib/osm/event.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Osm
|
2
2
|
|
3
3
|
class Event < Osm::Model
|
4
|
-
class Column; end # Ensure the constant exists for the validators
|
4
|
+
class Column < Osm::Model; end # Ensure the constant exists for the validators
|
5
5
|
|
6
6
|
# @!attribute [rw] id
|
7
7
|
# @return [Fixnum] the id for the event
|
@@ -21,9 +21,6 @@ module Osm
|
|
21
21
|
# @return [String] notes about the event
|
22
22
|
# @!attribute [rw] archived
|
23
23
|
# @return [Boolean] if the event has been archived
|
24
|
-
# @!attribute [rw] fields
|
25
|
-
# @deprecated use columns instead
|
26
|
-
# @return [Hash] Keys are the field's id, values are the field names
|
27
24
|
# @!attribute [rw] columns
|
28
25
|
# @return [Array<Osm::Event::Column>] the custom columns for the event
|
29
26
|
# @!attribute [rw] notepad
|
@@ -75,36 +72,41 @@ module Osm
|
|
75
72
|
|
76
73
|
# @!method initialize
|
77
74
|
# Initialize a new Event
|
78
|
-
# @param [Hash] attributes
|
75
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
79
76
|
|
80
77
|
|
81
78
|
# Get events for a section
|
82
79
|
# @param [Osm::Api] api The api to use to make the request
|
83
|
-
# @param [Osm::Section, Fixnum] section
|
80
|
+
# @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the events for
|
84
81
|
# @!macro options_get
|
85
82
|
# @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
|
86
83
|
# @return [Array<Osm::Event>]
|
87
84
|
def self.get_for_section(api, section, options={})
|
85
|
+
require_ability_to(api, :read, :events, section, options)
|
88
86
|
section_id = section.to_i
|
89
87
|
cache_key = ['events', section_id]
|
90
88
|
events = nil
|
91
89
|
|
92
|
-
if !options[:no_cache] && cache_exist?(api, cache_key)
|
93
|
-
|
90
|
+
if !options[:no_cache] && cache_exist?(api, cache_key)
|
91
|
+
ids = cache_read(api, cache_key)
|
92
|
+
events = get_from_ids(api, ids, 'event', section, options, :get_for_section)
|
94
93
|
end
|
95
94
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
data['items'].
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
95
|
+
if events.nil?
|
96
|
+
data = api.perform_query("events.php?action=getEvents§ionid=#{section_id}&showArchived=true")
|
97
|
+
events = Array.new
|
98
|
+
ids = Array.new
|
99
|
+
unless data['items'].nil?
|
100
|
+
data['items'].map { |i| i['eventid'].to_i }.each do |event_id|
|
101
|
+
event_data = api.perform_query("events.php?action=getEvent§ionid=#{section_id}&eventid=#{event_id}")
|
102
|
+
event = self.new_event_from_data(event_data)
|
103
|
+
events.push event
|
104
|
+
ids.push event.id
|
105
|
+
cache_write(api, ['event', event.id], event)
|
106
|
+
end
|
105
107
|
end
|
108
|
+
cache_write(api, cache_key, ids)
|
106
109
|
end
|
107
|
-
cache_write(api, cache_key, events)
|
108
110
|
|
109
111
|
return events if options[:include_archived]
|
110
112
|
return events.reject do |event|
|
@@ -114,16 +116,17 @@ module Osm
|
|
114
116
|
|
115
117
|
# Get an event
|
116
118
|
# @param [Osm::Api] api The api to use to make the request
|
117
|
-
# @param [Osm::Section, Fixnum] section
|
118
|
-
# @param [Fixnum] event_id
|
119
|
+
# @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the events for
|
120
|
+
# @param [Fixnum] event_id The id of the event to get
|
119
121
|
# @!macro options_get
|
120
122
|
# @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
|
121
123
|
# @return [Osm::Event, nil] the event (or nil if it couldn't be found
|
122
124
|
def self.get(api, section, event_id, options={})
|
125
|
+
require_ability_to(api, :read, :events, section, options)
|
123
126
|
section_id = section.to_i
|
124
127
|
cache_key = ['event', event_id]
|
125
128
|
|
126
|
-
if !options[:no_cache] && cache_exist?(api, cache_key)
|
129
|
+
if !options[:no_cache] && cache_exist?(api, cache_key)
|
127
130
|
return cache_read(api, cache_key)
|
128
131
|
end
|
129
132
|
|
@@ -135,10 +138,11 @@ module Osm
|
|
135
138
|
# Create an event in OSM
|
136
139
|
# @param [Osm::Api] api The api to use to make the request
|
137
140
|
# @return [Osm::Event, nil] the created event, nil if failed
|
141
|
+
# @raise [Osm::ObjectIsInvalid] If the Event is invalid
|
138
142
|
def self.create(api, parameters)
|
143
|
+
require_ability_to(api, :write, :events, parameters[:section_id])
|
139
144
|
event = new(parameters)
|
140
|
-
raise ObjectIsInvalid, 'event is invalid' unless event.valid?
|
141
|
-
raise Forbidden, 'you do not have permission to write to events for this section' unless get_user_permission(api, event.section_id, :events).include?(:write)
|
145
|
+
raise Osm::ObjectIsInvalid, 'event is invalid' unless event.valid?
|
142
146
|
|
143
147
|
data = api.perform_query("events.php?action=addEvent§ionid=#{event.section_id}", {
|
144
148
|
'name' => event.name,
|
@@ -172,7 +176,9 @@ module Osm
|
|
172
176
|
# @param [Osm::Api] api The api to use to make the request
|
173
177
|
# @return [Boolean] whether the update succedded
|
174
178
|
def update(api)
|
175
|
-
|
179
|
+
require_ability_to(api, :write, :events, section_id)
|
180
|
+
|
181
|
+
to_update = changed_attributes
|
176
182
|
|
177
183
|
data = api.perform_query("events.php?action=addEvent§ionid=#{section_id}", {
|
178
184
|
'eventid' => id,
|
@@ -190,49 +196,55 @@ module Osm
|
|
190
196
|
'attendancelimit' => attendance_limit,
|
191
197
|
'limitincludesleaders' => attendance_limit_includes_leaders,
|
192
198
|
})
|
199
|
+
|
193
200
|
api.perform_query("events.php?action=saveNotepad§ionid=#{section_id}", {
|
194
201
|
'eventid' => id,
|
195
202
|
'notepad' => notepad,
|
196
|
-
})
|
203
|
+
}) if to_update.include?('notepad')
|
204
|
+
|
197
205
|
api.perform_query("events.php?action=saveNotepad§ionid=#{section_id}", {
|
198
206
|
'eventid' => id,
|
199
207
|
'pnnotepad' => public_notepad,
|
200
|
-
})
|
201
|
-
|
202
|
-
# The cached events for the section will be out of date - remove them
|
203
|
-
cache_delete(api, ['event', id])
|
204
|
-
cache_delete(api, ['events', section_id])
|
208
|
+
}) if to_update.include?('public_notepad')
|
205
209
|
|
206
|
-
|
210
|
+
if data.is_a?(Hash) && (data['id'].to_i == id)
|
211
|
+
reset_changed_attributes
|
212
|
+
# The cached event will be out of date - remove it
|
213
|
+
cache_delete(api, ['event', id])
|
214
|
+
return true
|
215
|
+
else
|
216
|
+
return false
|
217
|
+
end
|
207
218
|
end
|
208
219
|
|
209
220
|
# Delete event from OSM
|
210
221
|
# @param [Osm::Api] api The api to use to make the request
|
211
222
|
# @return [Boolean] whether the delete succedded
|
212
223
|
def delete(api)
|
213
|
-
|
224
|
+
require_ability_to(api, :write, :events, section_id)
|
214
225
|
|
215
226
|
data = api.perform_query("events.php?action=deleteEvent§ionid=#{section_id}&eventid=#{id}")
|
216
227
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
return
|
228
|
+
if data.is_a?(Hash) && data['ok']
|
229
|
+
cache_delete(api, ['event', id])
|
230
|
+
return true
|
231
|
+
end
|
232
|
+
return false
|
222
233
|
end
|
223
234
|
|
224
235
|
|
225
236
|
# Get event attendance
|
226
237
|
# @param [Osm::Api] api The api to use to make the request
|
227
|
-
# @param [Osm::Term, Fixnum, nil] term
|
238
|
+
# @param [Osm::Term, Fixnum, #to_i, nil] term The term (or its ID) to get the members for, passing nil causes the current term to be used
|
228
239
|
# @!macro options_get
|
229
240
|
# @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
|
230
241
|
# @return [Array<Osm::Event::Attendance>]
|
231
242
|
def get_attendance(api, term=nil, options={})
|
243
|
+
require_ability_to(api, :read, :events, section_id, options)
|
232
244
|
term_id = term.nil? ? Osm::Term.get_current_term_for_section(api, section_id).id : term.to_i
|
233
245
|
cache_key = ['event_attendance', id]
|
234
246
|
|
235
|
-
if !options[:no_cache] && cache_exist?(api, cache_key)
|
247
|
+
if !options[:no_cache] && cache_exist?(api, cache_key)
|
236
248
|
return cache_read(api, cache_key)
|
237
249
|
end
|
238
250
|
|
@@ -264,12 +276,13 @@ module Osm
|
|
264
276
|
|
265
277
|
# Add a column to the event in OSM
|
266
278
|
# @param [Osm::Api] api The api to use to make the request
|
267
|
-
# @param [String] label
|
268
|
-
# @param [String] name
|
279
|
+
# @param [String] label The label for the field in OSM
|
280
|
+
# @param [String] name The label for the field in My.SCOUT (if this is blank then parents can't edit it)
|
269
281
|
# @return [Boolean] whether the update succedded
|
282
|
+
# @raise [Osm::ArgumentIsInvalid] If the name is blank
|
270
283
|
def add_column(api, name, label='')
|
271
|
-
|
272
|
-
raise
|
284
|
+
require_ability_to(api, :write, :events, section_id)
|
285
|
+
raise Osm::ArgumentIsInvalid, 'name is invalid' if name.blank?
|
273
286
|
|
274
287
|
data = api.perform_query("events.php?action=addColumn§ionid=#{section_id}&eventid=#{id}", {
|
275
288
|
'columnName' => name,
|
@@ -286,41 +299,8 @@ module Osm
|
|
286
299
|
return data.is_a?(Hash) && (data['eventid'].to_i == id)
|
287
300
|
end
|
288
301
|
|
289
|
-
#
|
290
|
-
# @
|
291
|
-
# @param [Osm::Api] api The api to use to make the request
|
292
|
-
# @param [String] field_label the label for the field to add
|
293
|
-
# @return [Boolean] whether the update succedded
|
294
|
-
# TODO - Remove this method when upping the version
|
295
|
-
def add_field(api, label)
|
296
|
-
warn "[DEPRECATION OF METHOD] this method is being depreiated, use add_column instead"
|
297
|
-
raise ArgumentIsInvalid, 'label is invalid' if label.blank?
|
298
|
-
raise Forbidden, 'you do not have permission to write to events for this section' unless get_user_permission(api, section_id, :events).include?(:write)
|
299
|
-
|
300
|
-
data = api.perform_query("events.php?action=addColumn§ionid=#{section_id}&eventid=#{id}", {
|
301
|
-
'columnName' => label,
|
302
|
-
'parentLabel' => ''
|
303
|
-
})
|
304
|
-
|
305
|
-
# The cached events for the section will be out of date - remove them
|
306
|
-
cache_delete(api, ['events', section_id])
|
307
|
-
cache_delete(api, ['event', id])
|
308
|
-
cache_delete(api, ['event_attendance', id])
|
309
|
-
|
310
|
-
return data.is_a?(Hash) && (data['eventid'].to_i == id)
|
311
|
-
end
|
312
|
-
|
313
|
-
|
314
|
-
# TODO - Remove this attribute when upping the version
|
315
|
-
def fields
|
316
|
-
warn "[DEPRECATION OF ATTRIBUTE] this attribute is being depreiated, in favor of returning an array of Field objects."
|
317
|
-
return columns.inject({}){ |h,(c)| h[c.id] = c.name; h}
|
318
|
-
end
|
319
|
-
def fields=(value)
|
320
|
-
raise "[DEPRECATION OF ATTRIBUTE] this attribute is being depreiated, in favor of returning an array of Field objects."
|
321
|
-
end
|
322
|
-
|
323
|
-
|
302
|
+
# Whether thete is a limit on attendance for this event
|
303
|
+
# @return [Boolean] whether thete is a limit on attendance for this event
|
324
304
|
def limited_attendance?
|
325
305
|
(attendance_limit != 0)
|
326
306
|
end
|
@@ -380,10 +360,7 @@ module Osm
|
|
380
360
|
end
|
381
361
|
|
382
362
|
|
383
|
-
class Column
|
384
|
-
include ::ActiveAttr::MassAssignmentSecurity
|
385
|
-
include ::ActiveAttr::Model
|
386
|
-
|
363
|
+
class Column < Osm::Model
|
387
364
|
# @!attribute [rw] id
|
388
365
|
# @return [String] OSM id for the column
|
389
366
|
# @!attribute [rw] name
|
@@ -406,14 +383,14 @@ module Osm
|
|
406
383
|
|
407
384
|
# @!method initialize
|
408
385
|
# Initialize a new Column
|
409
|
-
# @param [Hash] attributes
|
386
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
410
387
|
|
411
388
|
|
412
389
|
# Update event column in OSM
|
413
390
|
# @param [Osm::Api] api The api to use to make the request
|
414
391
|
# @return [Boolean] if the operation suceeded or not
|
415
392
|
def update(api)
|
416
|
-
|
393
|
+
require_ability_to(api, :write, :events, event.section_id)
|
417
394
|
|
418
395
|
data = api.perform_query("events.php?action=renameColumn§ionid=#{event.section_id}&eventid=#{event.id}", {
|
419
396
|
'columnId' => id,
|
@@ -421,13 +398,16 @@ module Osm
|
|
421
398
|
'pL' => label
|
422
399
|
})
|
423
400
|
|
424
|
-
# The cached events for the section will be out of date - remove them
|
425
|
-
Osm::Model.cache_delete(api, ['events', event.section_id])
|
426
|
-
Osm::Model.cache_delete(api, ['event', event.id])
|
427
|
-
|
428
401
|
(ActiveSupport::JSON.decode(data['config']) || []).each do |i|
|
429
402
|
if i['id'] == id
|
430
|
-
|
403
|
+
if i['name'].eql?(name) && (i['pL'].nil? || i['pL'].eql?(label))
|
404
|
+
reset_changed_attributes
|
405
|
+
# The cached event will be out of date - remove it
|
406
|
+
cache_delete(api, ['event', event.id])
|
407
|
+
# The cached event attedance will be out of date
|
408
|
+
cache_delete(api, ['event_attendance', event.id])
|
409
|
+
return true
|
410
|
+
end
|
431
411
|
end
|
432
412
|
end
|
433
413
|
return false
|
@@ -437,16 +417,12 @@ module Osm
|
|
437
417
|
# @param [Osm::Api] api The api to use to make the request
|
438
418
|
# @return [Boolean] whether the delete succedded
|
439
419
|
def delete(api)
|
440
|
-
|
420
|
+
require_ability_to(api, :write, :events, event.section_id)
|
441
421
|
|
442
422
|
data = api.perform_query("events.php?action=deleteColumn§ionid=#{event.section_id}&eventid=#{event.id}", {
|
443
423
|
'columnId' => id
|
444
424
|
})
|
445
425
|
|
446
|
-
# The cached events for the section will be out of date - remove them
|
447
|
-
Osm::Model.cache_delete(api, ['events', event.section_id])
|
448
|
-
Osm::Model.cache_delete(api, ['event', event.id])
|
449
|
-
|
450
426
|
(ActiveSupport::JSON.decode(data['config']) || []).each do |i|
|
451
427
|
return false if i['id'] == id
|
452
428
|
end
|
@@ -456,16 +432,15 @@ module Osm
|
|
456
432
|
new_columns.push(column) unless column == self
|
457
433
|
end
|
458
434
|
event.columns = new_columns
|
435
|
+
|
436
|
+
cache_write(api, ['event', event.id], event)
|
459
437
|
return true
|
460
438
|
end
|
461
439
|
|
462
440
|
end # class Column
|
463
441
|
|
464
442
|
|
465
|
-
class Attendance
|
466
|
-
include ::ActiveAttr::MassAssignmentSecurity
|
467
|
-
include ::ActiveAttr::Model
|
468
|
-
|
443
|
+
class Attendance < Osm::Model
|
469
444
|
# @!attribute [rw] member_id
|
470
445
|
# @return [Fixnum] OSM id for the member
|
471
446
|
# @!attribute [rw] grouping__id
|
@@ -496,16 +471,17 @@ module Osm
|
|
496
471
|
|
497
472
|
# @!method initialize
|
498
473
|
# Initialize a new Attendance
|
499
|
-
# @param [Hash] attributes
|
474
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
500
475
|
|
501
476
|
|
502
477
|
# Update event attendance
|
503
478
|
# @param [Osm::Api] api The api to use to make the request
|
504
|
-
# @param [String] field_id
|
479
|
+
# @param [String] field_id The id of the field to update (must be 'attending' or /\Af_\d+\Z/)
|
505
480
|
# @return [Boolean] if the operation suceeded or not
|
481
|
+
# @raise [Osm::ArgumentIsInvalid] If field_id does not match the pattern "f_#{number}" or is "attending"
|
506
482
|
def update(api, field_id)
|
507
|
-
|
508
|
-
raise
|
483
|
+
require_ability_to(api, :write, :events, event.section_id)
|
484
|
+
raise Osm::ArgumentIsInvalid, 'field_id is invalid' unless field_id.match(/\Af_\d+\Z/) || field_id.eql?('attending')
|
509
485
|
|
510
486
|
data = api.perform_query("events.php?action=updateScout", {
|
511
487
|
'scoutid' => member_id,
|
@@ -515,11 +491,15 @@ module Osm
|
|
515
491
|
'row' => row,
|
516
492
|
'eventid' => event.id,
|
517
493
|
})
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
494
|
+
|
495
|
+
if data.is_a?(Hash)
|
496
|
+
reset_changed_attributes
|
497
|
+
# The cached event attedance will be out of date
|
498
|
+
Osm::Model.cache_delete(api, ['event_attendance', event.id])
|
499
|
+
return true
|
500
|
+
else
|
501
|
+
return false
|
502
|
+
end
|
523
503
|
end
|
524
504
|
|
525
505
|
end # Class Attendance
|
data/lib/osm/flexi_record.rb
CHANGED
@@ -1,32 +1,46 @@
|
|
1
|
-
# TODO make 'proper' class
|
2
|
-
|
3
1
|
module Osm
|
4
2
|
|
5
|
-
class FlexiRecord
|
3
|
+
class FlexiRecord < Osm::Model
|
4
|
+
# @!attribute [rw] id
|
5
|
+
# @return [Fixnum] the id for the flexi_record
|
6
|
+
# @!attribute [rw] section_id
|
7
|
+
# @return [Fixnum] the section the member belongs to
|
8
|
+
# @!attribute [rw] name
|
9
|
+
# @return [String] the flexi record's name name
|
10
|
+
|
11
|
+
attribute :id, :type => Integer
|
12
|
+
attribute :section_id, :type => Integer
|
13
|
+
attribute :name, :type => String
|
14
|
+
|
15
|
+
attr_accessible :id, :section_id, :name
|
16
|
+
|
17
|
+
validates_numericality_of :id, :only_integer=>true, :greater_than=>0, :unless => Proc.new { |r| r.id.nil? }
|
18
|
+
validates_numericality_of :section_id, :only_integer=>true, :greater_than=>0
|
19
|
+
validates_presence_of :name
|
6
20
|
|
7
|
-
|
21
|
+
|
22
|
+
# Get structure for the flexi record
|
8
23
|
# @param [Osm::Api] api The api to use to make the request
|
9
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
|
10
|
-
# @param [Fixnum] id the id of the Flexi Record
|
11
24
|
# @!macro options_get
|
12
|
-
# @return [Array<Osm::
|
13
|
-
def
|
14
|
-
section_id
|
15
|
-
cache_key = ['
|
25
|
+
# @return [Array<Osm::FlexiRecordColumn>] representing the columns of the flexi record
|
26
|
+
def get_columns(api, options={})
|
27
|
+
require_ability_to(api, :read, :flexi, section_id, options)
|
28
|
+
cache_key = ['flexi_record_columns', self.id]
|
16
29
|
|
17
|
-
if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
|
30
|
+
if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
|
18
31
|
return Osm::Model.cache_read(api, cache_key)
|
19
32
|
end
|
20
33
|
|
21
|
-
data = api.perform_query("extras.php?action=getExtra§ionid=#{section_id}&extraid=#{id}")
|
34
|
+
data = api.perform_query("extras.php?action=getExtra§ionid=#{self.section_id}&extraid=#{self.id}")
|
22
35
|
|
23
36
|
structure = []
|
24
37
|
data['structure'].each do |item|
|
25
38
|
item['rows'].each do |row|
|
26
|
-
structure.push Osm::FlexiRecord::
|
39
|
+
structure.push Osm::FlexiRecord::Column.new(
|
27
40
|
:id => row['field'],
|
28
41
|
:name => row['name'],
|
29
42
|
:editable => row['editable'] || false,
|
43
|
+
:flexi_record => self,
|
30
44
|
)
|
31
45
|
end
|
32
46
|
end
|
@@ -35,15 +49,13 @@ module Osm
|
|
35
49
|
return structure
|
36
50
|
end
|
37
51
|
|
38
|
-
# Add a
|
52
|
+
# Add a column in OSM
|
39
53
|
# @param [Osm::Api] api The api to use to make the request
|
40
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
|
41
|
-
# @param [Fixnum] id the id of the Flexi Record
|
42
54
|
# @param [String] name The name for the created column
|
43
|
-
# @return [Boolean] whether the
|
44
|
-
def
|
55
|
+
# @return [Boolean] whether the column was created in OSM
|
56
|
+
def add_column(api, name)
|
57
|
+
require_ability_to(api, :write, :flexi, section_id)
|
45
58
|
raise ArgumentError, 'name is invalid' if name.blank?
|
46
|
-
section_id = section.to_i
|
47
59
|
|
48
60
|
data = api.perform_query("extras.php?action=addColumn§ionid=#{section_id}&extraid=#{id}", {
|
49
61
|
'columnName' => name,
|
@@ -53,35 +65,7 @@ module Osm
|
|
53
65
|
ActiveSupport::JSON.decode(data['config']).each do |field|
|
54
66
|
if field['name'] == name
|
55
67
|
# The cached fields for the flexi record will be out of date - remove them
|
56
|
-
Osm::Model.cache_delete(api, ['
|
57
|
-
return true
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
return false
|
62
|
-
end
|
63
|
-
|
64
|
-
# Update a field in OSM
|
65
|
-
# @param [Osm::Api] api The api to use to make the request
|
66
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
|
67
|
-
# @param [Fixnum] id the id of the Flexi Record
|
68
|
-
# @param [String] field the id of the Flexi Record Field
|
69
|
-
# @param [String] name The new name for the created column
|
70
|
-
# @return [Boolean] whether the field was updated in OSM
|
71
|
-
def self.update_field(api, section, id, field, name)
|
72
|
-
raise ArgumentError, 'name is invalid' if name.blank?
|
73
|
-
section_id = section.to_i
|
74
|
-
|
75
|
-
data = api.perform_query("extras.php?action=renameColumn§ionid=#{section_id}&extraid=#{id}", {
|
76
|
-
'columnId' => field,
|
77
|
-
'columnName' => name,
|
78
|
-
})
|
79
|
-
|
80
|
-
if (data.is_a?(Hash) && data.has_key?('config'))
|
81
|
-
ActiveSupport::JSON.decode(data['config']).each do |f|
|
82
|
-
if (f['id'] == field) && (f['name'] == name)
|
83
|
-
# The cached fields for the flexi record will be out of date - remove them
|
84
|
-
Osm::Model.cache_delete(api, ['flexi_record_fields', id])
|
68
|
+
Osm::Model.cache_delete(api, ['flexi_record_columns', id])
|
85
69
|
return true
|
86
70
|
end
|
87
71
|
end
|
@@ -89,46 +73,18 @@ module Osm
|
|
89
73
|
return false
|
90
74
|
end
|
91
75
|
|
92
|
-
# Update a field in OSM
|
93
|
-
# @param [Osm::Api] api The api to use to make the request
|
94
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
|
95
|
-
# @param [Fixnum] id the id of the Flexi Record
|
96
|
-
# @param [String] field the id of the Flexi Record Field
|
97
|
-
# @return [Boolean] whether the field was updated in OSM
|
98
|
-
def self.delete_field(api, section, id, field)
|
99
|
-
section_id = section.to_i
|
100
|
-
|
101
|
-
data = api.perform_query("extras.php?action=deleteColumn§ionid=#{section_id}&extraid=#{id}", {
|
102
|
-
'columnId' => field,
|
103
|
-
})
|
104
|
-
|
105
|
-
if (data.is_a?(Hash) && data.has_key?('config'))
|
106
|
-
ActiveSupport::JSON.decode(data['config']).each do |f|
|
107
|
-
if f['id'] == field
|
108
|
-
# It wasn't deleted
|
109
|
-
return false
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# The cached fields for the flexi record will be out of date - remove them
|
115
|
-
Osm::Model.cache_delete(api, ['flexi_record_fields', id])
|
116
|
-
return true
|
117
|
-
end
|
118
|
-
|
119
76
|
# Get data for flexi record
|
120
77
|
# @param [Osm::Api] api The api to use to make the request
|
121
|
-
# @param [Osm::
|
122
|
-
# @param [Fixnum] the id of the Flexi Record
|
123
|
-
# @param [Osm::Term, Fixnum, nil] section the term (or its ID) to get the register for, passing nil causes the current term to be used
|
78
|
+
# @param [Osm::Term, Fixnum, #to_i, nil] term The term (or its ID) to get the register for, passing nil causes the current term to be used
|
124
79
|
# @!macro options_get
|
125
80
|
# @return [Array<FlexiRecordData>]
|
126
|
-
def
|
127
|
-
|
81
|
+
def get_data(api, term=nil, options={})
|
82
|
+
require_ability_to(api, :read, :flexi, section_id, options)
|
83
|
+
section = Osm::Section.get(api, self.section_id)
|
128
84
|
term_id = term.nil? ? Osm::Term.get_current_term_for_section(api, section).id : term.to_i
|
129
85
|
cache_key = ['flexi_record_data', id, term_id]
|
130
86
|
|
131
|
-
if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
|
87
|
+
if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
|
132
88
|
return Osm::Model.cache_read(api, cache_key)
|
133
89
|
end
|
134
90
|
|
@@ -150,7 +106,8 @@ module Osm
|
|
150
106
|
to_return.push Osm::FlexiRecord::Data.new(
|
151
107
|
:member_id => Osm::to_i_or_nil(item['scoutid']),
|
152
108
|
:grouping_id => Osm::to_i_or_nil(item['patrolid'].eql?('') ? nil : item['patrolid']),
|
153
|
-
:fields => fields
|
109
|
+
:fields => fields,
|
110
|
+
:flexi_record => self,
|
154
111
|
)
|
155
112
|
end
|
156
113
|
end
|
@@ -159,40 +116,20 @@ module Osm
|
|
159
116
|
return to_return
|
160
117
|
end
|
161
118
|
|
162
|
-
# Update a field in OSM
|
163
|
-
# @param [Osm::Api] api The api to use to make the request
|
164
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to update the data for
|
165
|
-
# @param [Fixnum] flexi_record_id the id of the Flexi Record
|
166
|
-
# @param [Osm::Member, Fixnum] member the member (or their ID) to update
|
167
|
-
# @param [String] column the id of the Flexi Record Field
|
168
|
-
# @param [String] value The updated value
|
169
|
-
# @return [Boolean] whether the field was updated in OSM
|
170
|
-
def self.update_data(api, section, flexi_record_id, member, column, value)
|
171
|
-
raise ArgumentError, 'name is invalid' if name.blank?
|
172
|
-
section_id = section.to_i
|
173
|
-
member_id = member.to_i
|
174
|
-
term_id = Osm::Term.get_current_term_for_section(api, section).id
|
175
|
-
|
176
|
-
data = api.perform_query("extras.php?action=updateScout", {
|
177
|
-
'termid' => term_id,
|
178
|
-
'scoutid' => member_id,
|
179
|
-
'column' => column,
|
180
|
-
'value' => value,
|
181
|
-
'sectionid' => section_id,
|
182
|
-
'extraid' => flexi_record_id,
|
183
|
-
})
|
184
119
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
120
|
+
def <=>(another)
|
121
|
+
begin
|
122
|
+
return self.name <=> another.name
|
123
|
+
rescue NoMethodError
|
124
|
+
return 1
|
189
125
|
end
|
190
|
-
return false
|
191
126
|
end
|
192
127
|
|
193
128
|
|
194
129
|
|
195
|
-
class
|
130
|
+
class Column < Osm::Model
|
131
|
+
# @!attribute [rw] flexi_record
|
132
|
+
# @return [Boolean] The FlexiRecord this column belongs to
|
196
133
|
# @!attribute [rw] id
|
197
134
|
# @return [String] OSM identifier for the field. Special ones are 'dob', 'total', 'completed', 'age', 'firstname' and 'lastname', user ones are of the format 'f\_NUMBER'
|
198
135
|
# @!attribute [rw] name
|
@@ -200,24 +137,83 @@ module Osm
|
|
200
137
|
# @!attribute [rw] editable
|
201
138
|
# @return [Boolean] Wether the field can be edited
|
202
139
|
|
140
|
+
attribute :flexi_record, :type => Object
|
203
141
|
attribute :id, :type => String
|
204
142
|
attribute :name, :type => String
|
205
143
|
attribute :editable, :type => Boolean, :default => false
|
206
144
|
|
207
|
-
attr_accessible :id, :name, :editable
|
145
|
+
attr_accessible :flexi_record, :id, :name, :editable
|
208
146
|
|
147
|
+
validates_presence_of :flexi_record
|
209
148
|
validates_presence_of :id
|
210
149
|
validates_presence_of :name
|
211
150
|
validates_inclusion_of :editable, :in => [true, false]
|
212
151
|
|
213
152
|
# @!method initialize
|
214
|
-
# Initialize a new
|
215
|
-
# @param [Hash] attributes
|
153
|
+
# Initialize a new FlexiRecord::Column
|
154
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
155
|
+
|
156
|
+
|
157
|
+
# Update a column in OSM
|
158
|
+
# @param [Osm::Api] api The api to use to make the request
|
159
|
+
# @return [Boolean] whether the column was updated in OSM
|
160
|
+
# @raise [Osm::ObjectIsInvalid] If the Column is invalid
|
161
|
+
# @raise [Osm::Forbidden] If the COlumn is not editable
|
162
|
+
def update(api)
|
163
|
+
raise Osm::ObjectIsInvalid, 'column is invalid' unless valid?
|
164
|
+
require_ability_to(api, :write, :flexi, flexi_record.section_id)
|
165
|
+
raise Osm::Forbidden, 'this column is not editable' unless self.editable
|
166
|
+
|
167
|
+
data = api.perform_query("extras.php?action=renameColumn§ionid=#{flexi_record.section_id}&extraid=#{flexi_record.id}", {
|
168
|
+
'columnId' => self.id,
|
169
|
+
'columnName' => self.name,
|
170
|
+
})
|
171
|
+
|
172
|
+
if (data.is_a?(Hash) && data.has_key?('config'))
|
173
|
+
ActiveSupport::JSON.decode(data['config']).each do |f|
|
174
|
+
if (f['id'] == self.id) && (f['name'] == self.name)
|
175
|
+
reset_changed_attributes
|
176
|
+
# The cached columns for the flexi record will be out of date - remove them
|
177
|
+
cache_delete(api, ['flexi_record_columns', flexi_record.id])
|
178
|
+
return true
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
return false
|
183
|
+
end
|
216
184
|
|
217
|
-
|
185
|
+
# Delete a column in OSM
|
186
|
+
# @param [Osm::Api] api The api to use to make the request
|
187
|
+
# @return [Boolean] whether the column was deleted from OSM
|
188
|
+
# @raise [Osm::Forbidden] If this Column is not editable
|
189
|
+
def delete(api)
|
190
|
+
require_ability_to(api, :write, :flexi, flexi_record.section_id)
|
191
|
+
raise Osm::Forbidden, 'this column is not editable' unless self.editable
|
192
|
+
|
193
|
+
data = api.perform_query("extras.php?action=deleteColumn§ionid=#{flexi_record.section_id}&extraid=#{flexi_record.id}", {
|
194
|
+
'columnId' => self.id,
|
195
|
+
})
|
196
|
+
|
197
|
+
if (data.is_a?(Hash) && data.has_key?('config'))
|
198
|
+
ActiveSupport::JSON.decode(data['config']).each do |f|
|
199
|
+
if f['id'] == self.id
|
200
|
+
# It wasn't deleted
|
201
|
+
return false
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# The cached columns for the flexi record will be out of date - remove them
|
207
|
+
cache_delete(api, ['flexi_record_columns', flexi_record.id])
|
208
|
+
return true
|
209
|
+
end
|
210
|
+
|
211
|
+
end # Class FlexiRecord::Column
|
218
212
|
|
219
213
|
|
220
214
|
class Data < Osm::Model
|
215
|
+
# @!attribute [rw] flexi_record
|
216
|
+
# @return [Boolean] The FlexiRecord this column belongs to
|
221
217
|
# @!attribute [rw] member_id
|
222
218
|
# @return [Fixnum] OSM id for the member
|
223
219
|
# @!attribute [rw] grouping__id
|
@@ -225,20 +221,65 @@ module Osm
|
|
225
221
|
# @!attribute [rw] fields
|
226
222
|
# @return [Hash] Keys are the field's id, values are the field values
|
227
223
|
|
224
|
+
attribute :flexi_record, :type => Object
|
228
225
|
attribute :member_id, :type => Integer
|
229
226
|
attribute :grouping_id, :type => Integer
|
230
227
|
attribute :fields, :default => {}
|
231
228
|
|
232
|
-
attr_accessible :member_id, :grouping_id, :fields
|
229
|
+
attr_accessible :flexi_record, :member_id, :grouping_id, :fields
|
233
230
|
|
231
|
+
validates_presence_of :flexi_record
|
234
232
|
validates_numericality_of :member_id, :only_integer=>true, :greater_than=>0
|
235
233
|
validates_numericality_of :grouping_id, :only_integer=>true, :greater_than_or_equal_to=>-2
|
236
234
|
validates :fields, :hash => {:key_type => String}
|
237
235
|
|
238
236
|
# @!method initialize
|
239
|
-
# Initialize a new
|
240
|
-
# @param [Hash] attributes
|
241
|
-
|
237
|
+
# Initialize a new FlexiRecord::Data
|
238
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
239
|
+
|
240
|
+
|
241
|
+
# Update data in OSM
|
242
|
+
# @param [Osm::Api] api The api to use to make the request
|
243
|
+
# @return [Boolean] whether the data was updated in OSM
|
244
|
+
# @raise [Osm::ObjectIsInvalid] If the Data is invalid
|
245
|
+
def update(api)
|
246
|
+
raise Osm::ObjectIsInvalid, 'data is invalid' unless valid?
|
247
|
+
require_ability_to(api, :write, :flexi, flexi_record.section_id)
|
248
|
+
|
249
|
+
term_id = Osm::Term.get_current_term_for_section(api, flexi_record.section_id).id
|
250
|
+
|
251
|
+
updated = true
|
252
|
+
flexi_record.get_columns(api).each do |column|
|
253
|
+
if column.editable
|
254
|
+
data = api.perform_query("extras.php?action=updateScout", {
|
255
|
+
'termid' => term_id,
|
256
|
+
'scoutid' => self.member_id,
|
257
|
+
'column' => column.id,
|
258
|
+
'value' => fields[column.id],
|
259
|
+
'sectionid' => flexi_record.section_id,
|
260
|
+
'extraid' => flexi_record.id,
|
261
|
+
})
|
262
|
+
if (data.is_a?(Hash) && data['items'].is_a?(Array))
|
263
|
+
data['items'].each do |item|
|
264
|
+
if item['scoutid'] == member_id.to_s # Find this member from the list of all members
|
265
|
+
updated = false unless item[column.id] == self.fields[column.id]
|
266
|
+
end
|
267
|
+
end
|
268
|
+
else
|
269
|
+
updated = false
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
if updated
|
275
|
+
reset_changed_attributes
|
276
|
+
# The cached datas for the flexi record will be out of date - remove them
|
277
|
+
cache_delete(api, ['flexi_record_data', flexi_record.id])
|
278
|
+
end
|
279
|
+
|
280
|
+
return updated
|
281
|
+
end
|
282
|
+
|
242
283
|
end # Class FlexiRecord::Data
|
243
284
|
|
244
285
|
end # Class FlexiRecord
|