osm 1.2.14 → 1.2.15.dev

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/lib/osm/badges.rb CHANGED
@@ -17,9 +17,10 @@ module Osm
17
17
  return Osm::Model.cache_read(api, cache_key)
18
18
  end
19
19
 
20
- data = api.perform_query("challenges.php?action=getInitialBadges&type=core&sectionid=#{section.id}&section=#{section.type}&termid=#{term_id}")
21
- data = (data['stock'] || {}).select{ |k,v| !k.eql?('sectionid') }.
22
- inject({}){ |new_hash,(badge, level)| new_hash[badge] = level.to_i; new_hash }
20
+ data = api.perform_query("ext/badges/stock/?action=getBadgeStock&section=#{section.type}&section_id=#{section.id}&term_id=#{term_id}")
21
+ data = (data['items'] || [])
22
+ data.map!{ |i| [i['shortname'], i['stock']] }
23
+ data = Hash[data]
23
24
 
24
25
  Osm::Model.cache_write(api, cache_key, data)
25
26
  return data
@@ -28,22 +29,25 @@ module Osm
28
29
  # Update badge stock levels
29
30
  # @param [Osm::Api] api The api to use to make the request
30
31
  # @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to update ther badge stock for
31
- # @param [Sring, #to_s] badge_key The badge to set the stock level for
32
+ # @param [Fixnum, #to_i] badge_id The badge to set the stock level for
33
+ # @param [Fixnum, #to_i] badge_level The level of a staged badge to set the stock for (default 1)
32
34
  # @param [Fixnum, #to_i] stock_level How many of the provided badge there are
33
35
  # @return [Boolan] whether the update was successfull or not
34
- def self.update_stock(api, section, badge_key, stock_level)
36
+ def self.update_stock(api, section, badge_id, badge_level=1, stock_level)
35
37
  Osm::Model.require_ability_to(api, :write, :badge, section)
36
38
  section = Osm::Section.get(api, section) unless section.is_a?(Osm::Section)
37
39
 
38
40
  Osm::Model.cache_delete(api, ['badge_stock', section.id])
39
41
 
40
- data = api.perform_query("challenges.php?action=updateStock", {
42
+ data = api.perform_query("ext/badges.php?action=updateStock", {
41
43
  'stock' => stock_level,
42
- 'table' => badge_key,
43
44
  'sectionid' => section.id,
44
45
  'section' => section.type,
46
+ 'type' => 'current',
47
+ 'level' => badge_level.to_i,
48
+ 'badge_id' => badge_id.to_i,
45
49
  })
46
- return data.is_a?(Hash) && (data['sectionid'].to_i == section.id) && (data[badge_key.to_s].to_i == stock_level)
50
+ return data.is_a?(Hash) && data['ok']
47
51
  end
48
52
 
49
53
 
@@ -63,24 +67,25 @@ module Osm
63
67
  return Osm::Model.cache_read(api, cache_key)
64
68
  end
65
69
 
66
- data = api.perform_query("challenges.php?action=outstandingBadges&section=#{section.type}&sectionid=#{section.id}&termid=#{term_id}")
70
+ data = api.perform_query("ext/badges/due/?action=get&section=#{section.type}&sectionid=#{section.id}&termid=#{term_id}")
67
71
 
68
72
  data = {} unless data.is_a?(Hash) # OSM/OGM returns an empty array to represent no badges
69
- pending_raw = data['pending'] || {}
70
- descriptions_raw = data['description'] || {}
73
+ pending = data['pending'] || {}
71
74
 
72
75
  by_member = {}
73
76
  member_names = {}
74
77
  badge_names = {}
75
- pending_raw.each do |key, members|
78
+ badge_stock = {}
79
+
80
+ pending.each do |badge_identifier, members|
76
81
  members.each do |member|
77
- id = Osm.to_i_or_nil(member['scoutid'])
78
- description = descriptions_raw[key]['name'] + (descriptions_raw[key]['section'].eql?('staged') ? " (Level #{member['level']})" : '')
79
- description_key = key + (descriptions_raw[key]['section'].eql?('staged') ? "_#{member['level']}" : '_1')
80
- badge_names[description_key] = description
81
- by_member[id] ||= []
82
- by_member[id].push(description_key)
83
- member_names[id] = "#{member['firstname']} #{member['lastname']}"
82
+ badge_level_identifier = badge_identifier + "_#{member['completed']}"
83
+ member_id = Osm.to_i_or_nil(member['scout_id'])
84
+ badge_names[badge_level_identifier] = "#{member['label']} - #{member['name']}" + (!member['extra'].nil? ? " (#{member['extra']})" : '')
85
+ badge_stock[badge_level_identifier] = member['current_stock'].to_i
86
+ by_member[member_id] ||= []
87
+ by_member[member_id].push(badge_level_identifier)
88
+ member_names[member_id] = "#{member['firstname']} #{member['lastname']}"
84
89
  end
85
90
  end
86
91
 
@@ -88,6 +93,7 @@ module Osm
88
93
  :by_member => by_member,
89
94
  :member_names => member_names,
90
95
  :badge_names => badge_names,
96
+ :badge_stock => badge_stock,
91
97
  )
92
98
  Osm::Model.cache_write(api, cache_key, due_badges)
93
99
  return due_badges
@@ -105,13 +111,15 @@ module Osm
105
111
  attribute :badge_names, :default => {}
106
112
  attribute :by_member, :default => {}
107
113
  attribute :member_names, :default => {}
114
+ attribute :badge_stock, :default => {}
108
115
 
109
116
  if ActiveModel::VERSION::MAJOR < 4
110
- attr_accessible :badge_names, :by_member, :member_names
117
+ attr_accessible :badge_names, :by_member, :member_names, :badge_stock
111
118
  end
112
119
 
113
120
  validates :badge_names, :hash => {:key_type => String, :value_type => String}
114
121
  validates :member_names, :hash => {:key_type => Fixnum, :value_type => String}
122
+ validates :badge_stock, :hash => {:key_type => String, :value_type => Fixnum}
115
123
 
116
124
  validates_each :by_member do |record, attr, value|
117
125
  badge_names_keys = record.badge_names.keys
data/lib/osm/event.rb CHANGED
@@ -234,23 +234,15 @@ module Osm
234
234
 
235
235
  # The cached events for the section will be out of date - remove them
236
236
  cache_delete(api, ['events', event.section_id])
237
- cache_write(api, ['event', event.id], event)
238
237
 
239
238
  # Add badge links to OSM
240
239
  badges_created = true
241
240
  event.badges.each do |badge|
242
- badge_data = data = api.perform_query("ext/events/event/index.php?action=badgeAddToEvent&sectionid=#{event.section_id}&eventid=#{event.id}", {
243
- 'section' => badge.badge_section,
244
- 'badgetype' => badge.badge_type,
245
- 'badge' => badge.badge_key,
246
- 'columnname' => badge.requirement_key,
247
- 'data' => badge.data,
248
- 'newcolumnname' => badge.requirement_label,
249
- })
250
- badges_created = false unless badge_data.is_a?(Hash) && badge_data['ok']
241
+ badges_created &= event.add_badge_link(api, badge)
251
242
  end
252
243
 
253
244
  if badges_created
245
+ cache_write(api, ['event', event.id], event)
254
246
  return event
255
247
  else
256
248
  # Someting went wrong adding badges so return what OSM has
@@ -324,43 +316,28 @@ module Osm
324
316
  badges_to_delete = []
325
317
  original_badges.each do |badge|
326
318
  unless badges.include?(badge)
327
- badges_to_delete.push({
328
- 'section' => badge.badge_section,
329
- 'badge' => badge.badge_key,
330
- 'columnname' => badge.requirement_key,
331
- 'data' => badge.data,
332
- 'newcolumnname' => badge.requirement_label,
333
- 'badgetype' => badge.badge_type,
334
- })
319
+ badges_to_delete.push badge
335
320
  end
336
321
  end
337
- unless badges_to_delete.empty?
338
- data = api.perform_query("ext/events/event/index.php?action=badgeDeleteFromEvent&sectionid=#{section_id}&eventid=#{id}", {
339
- 'badgelinks' => badges_to_delete,
322
+ badges_to_delete.each do |badge|
323
+ data = api.perform_query("ext/badges/records/index.php?action=deleteBadgeLink&sectionid=#{section_id}", {
324
+ 'section' => badge.badge_section,
325
+ 'sectionid' => section_id,
326
+ 'type' => 'event',
327
+ 'id' => id,
328
+ 'badge_id' => badge.badge_id,
329
+ 'badge_version' => badge.badge_version,
330
+ 'column_id' => badge.requirement_id,
340
331
  })
341
- updated &= data.is_a?(Hash) && data['ok']
332
+ updated &= data.is_a?(Hash) && data['status']
342
333
  end
343
334
 
344
335
  # Added badges
345
- badges_to_add = []
346
336
  badges.each do |badge|
347
337
  unless original_badges.include?(badge)
348
- badges_to_add.push({
349
- 'section' => badge.badge_section,
350
- 'badge' => badge.badge_key,
351
- 'columnname' => badge.requirement_key,
352
- 'data' => badge.data,
353
- 'newcolumnname' => badge.requirement_label,
354
- 'badgetype' => badge.badge_type,
355
- })
338
+ updated &= add_badge_link(api, badge)
356
339
  end
357
340
  end
358
- unless badges_to_add.empty?
359
- data = api.perform_query("ext/events/event/index.php?action=badgeAddToEvent&sectionid=#{section_id}&eventid=#{id}", {
360
- 'badgelinks' => badges_to_add,
361
- })
362
- updated &= data.is_a?(Hash) && data['ok']
363
- end
364
341
  end # includes badges
365
342
 
366
343
  if updated
@@ -442,6 +419,26 @@ module Osm
442
419
  return attendance
443
420
  end
444
421
 
422
+ # Add a badge link to the event in OSM
423
+ # @param [Osm::Api] api The api to use to make the request
424
+ # @param [Osm::Event::BadgeLink] link The badge link to add, if column_id is nil then a new column is created with requirement_label as the name
425
+ # @return [Boolean] whether the update succedded
426
+ def add_badge_link(api, link)
427
+ raise Osm::ObjectIsInvalid, 'link is invalid' unless link.valid?
428
+
429
+ data = api.perform_query("ext/badges/records/index.php?action=linkBadgeToItem&sectionid=#{section_id}", {
430
+ 'section' => link.badge_section,
431
+ 'sectionid' => section_id,
432
+ 'type' => 'event',
433
+ 'id' => id,
434
+ 'badge_id' => link.badge_id,
435
+ 'badge_version' => link.badge_version,
436
+ 'column_id' => link.requirement_id.to_i.eql?(0) ? -2 : link.requirement_id,
437
+ 'column_data' => link.data,
438
+ 'new_column_name' => link.requirement_id.to_i.eql?(0) ? link.requirement_label : '',
439
+ })
440
+ return (data.is_a?(Hash) && data['status'])
441
+ end
445
442
 
446
443
  # Add a column to the event in OSM
447
444
  # @param [Osm::Api] api The api to use to make the request
@@ -563,7 +560,16 @@ module Osm
563
560
  badges_data = event_data['badgelinks']
564
561
  badges_data = [] unless badges_data.is_a?(Array)
565
562
  badges_data.each do |field|
566
- badges.push BadgeLink.new(badge_key: field['badge'], badge_type: field['badgetype'].to_sym, badge_section: field['section'].to_sym, requirement_key: field['columnname'], badge_label: field['badgeLongName'], requirement_label: field['columnnameLongName'], data: field['data'])
563
+ badges.push BadgeLink.new(
564
+ badge_type: field['badgetype'].to_sym,
565
+ badge_section: field['section'].to_sym,
566
+ requirement_id: field['column_id'],
567
+ badge_name: field['badgeLongName'],
568
+ requirement_label: field['columnnameLongName'],
569
+ data: field['data'],
570
+ badge_id: field['badge_id'],
571
+ badge_version: field['badge_version'],
572
+ )
567
573
  end
568
574
  event.badges = badges
569
575
 
@@ -571,52 +577,54 @@ module Osm
571
577
  end
572
578
 
573
579
 
574
- # When creating a BadgeLink for an existing column in a hikes/nights badge the requirement_label is optional
575
- # When creating a BadgeLink for a new column in a hikes/nights badge the requirement_key MUST be blank
576
- # TODO : Add validation for above statements
577
580
  class BadgeLink
578
581
  include ActiveModel::MassAssignmentSecurity if ActiveModel::VERSION::MAJOR < 4
579
582
  include ActiveAttr::Model
580
583
 
581
- # @!attribute [rw] badge_key
582
- # @return [String] the badge being done
583
584
  # @!attribute [rw] badge_type
584
585
  # @return [Symbol] the type of badge
585
- # @!attribute [rw] badge_label
586
- # @return [String] human friendly badge name
587
- # @!attribute [rw] requirement_key
588
- # @return [String] the requirement being done
589
586
  # @!attribute [rw] badge_section
590
587
  # @return [Symbol] the section type that the badge belongs to
591
588
  # @!attribute [rw] requirement_label
592
589
  # @return [String] human firendly requirement label
593
590
  # @!attribute [rw] data
594
591
  # @return [String] what to put in the column when the badge records are updated
592
+ # @!attribute [rw] badge_name
593
+ # @return [String] the badge's name
594
+ # @!attribute [rw] badge_id
595
+ # @return [Fixnum] the badge's ID in OSM
596
+ # @!attribute [rw] badge_version
597
+ # @return [Fixnum] the version of the badge
598
+ # @!attribute [rw] requirement_id
599
+ # @return [Fixnum] the requirement's ID in OSM
595
600
 
596
- attribute :badge_key, :type => String
597
601
  attribute :badge_type, :type => Object
598
- attribute :requirement_key, :type => String
599
602
  attribute :badge_section, :type => Object
600
- attribute :badge_label, :type => String
601
603
  attribute :requirement_label, :type => String
602
604
  attribute :data, :type => String
605
+ attribute :badge_name, :type => String
606
+ attribute :badge_id, :type => Integer
607
+ attribute :badge_version, :type => Integer
608
+ attribute :requirement_id, :type => Integer
603
609
 
604
610
  if ActiveModel::VERSION::MAJOR < 4
605
- attr_accessible :badge_key, :badge_type, :requirement_key, :badge_section, :badge_label, :requirement_label, :data
611
+ attr_accessible :badge_type, :badge_section, :requirement_label, :data, :badge_name, :badge_id, :badge_version, :requirement_id
606
612
  end
607
613
 
608
- validates_presence_of :badge_key
609
- validates_format_of :requirement_key, :with => /\A(?:[a-z]_\d{2})|(?:custom_\d+)\Z/, :allow_blank => true, :message => 'is not in the correct format (e.g. "a_01")'
614
+ validates_presence_of :badge_name
610
615
  validates_inclusion_of :badge_section, :in => [:beavers, :cubs, :scouts, :explorers, :staged]
611
616
  validates_inclusion_of :badge_type, :in => [:core, :staged, :activity, :challenge]
617
+ validates_numericality_of :badge_id, :only_integer=>true, :greater_than=>0
618
+ validates_numericality_of :badge_version, :only_integer=>true, :greater_than_or_equal_to=>0
619
+ validates_numericality_of :requirement_id, :only_integer=>true, :greater_than=>0, :allow_nil=>true
612
620
 
613
621
  # @!method initialize
614
622
  # Initialize a new Meeting::Activity
615
623
  # @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
616
624
 
617
- # Compare BadgeLink based on section, type, key, requirement, data
625
+ # Compare BadgeLink based on section, type, badge_name, requirement_label, data
618
626
  def <=>(another)
619
- [:badge_section, :badge_type, :badge_key, :requirement_key].each do |attribute|
627
+ [:badge_section, :badge_type, :badge_name, :requirement_label].each do |attribute|
620
628
  result = self.try(:data) <=> another.try(:data)
621
629
  return result unless result == 0
622
630
  end
data/lib/osm/meeting.rb CHANGED
@@ -116,13 +116,16 @@ module Osm
116
116
  our_badge_links = badge_links[item['eveningid']]
117
117
  attributes[:badge_links] = Array.new
118
118
  unless our_badge_links.nil?
119
- our_badge_links.each do |badge_link_data|
119
+ our_badge_links.each do |badge_data|
120
120
  attributes[:badge_links].push Osm::Meeting::BadgeLink.new(
121
- :badge_key => badge_link_data['badge'],
122
- :badge_type => badge_link_data['badgetype'].downcase.to_sym,
123
- :requirement_key => badge_link_data['columnname'],
124
- :badge_section => badge_link_data['section'].downcase.to_sym,
125
- :label => badge_link_data['label'],
121
+ :badge_type => badge_data['badgetype'].to_sym,
122
+ :badge_section => badge_data['section'].to_sym,
123
+ :badge_name => badge_data['badgeLongName'],
124
+ :badge_id => Osm::to_i_or_nil(badge_data['badge_id']),
125
+ :badge_version => Osm::to_i_or_nil(badge_data['badge_version']),
126
+ :requirement_id => Osm::to_i_or_nil(badge_data['column_id']),
127
+ :requirement_label => badge_data['columnnameLongName'],
128
+ :data => badge_data['data'],
126
129
  )
127
130
  end
128
131
  end
@@ -178,17 +181,6 @@ module Osm
178
181
  activities_data.push this_activity
179
182
  end
180
183
 
181
- badge_links_data = Array.new
182
- badge_links.each do |badge_link|
183
- this_badge_link = {
184
- 'section' => badge_link.badge_section,
185
- 'badge' => badge_link.badge_key,
186
- 'columnname' => badge_link.requirement_key,
187
- 'badgetype' => badge_link.badge_type,
188
- }
189
- badge_links_data.push this_badge_link
190
- end
191
-
192
184
  api_data = {
193
185
  'eveningid' => id,
194
186
  'sectionid' => section_id,
@@ -202,7 +194,22 @@ module Osm
202
194
  'games' => games,
203
195
  'leaders' => leaders,
204
196
  'activity' => ActiveSupport::JSON.encode(activities_data),
205
- 'badgelinks' => ActiveSupport::JSON.encode(badge_links_data),
197
+ 'badgelinks' => ActiveSupport::JSON.encode(badge_links.map{ |b|
198
+ {
199
+ 'badge_id' => b.badge_id.to_s,
200
+ 'badge_version' => b.badge_version.to_s,
201
+ 'column_id' => b.requirement_id.to_s,
202
+ 'badge' => nil,
203
+ 'badgeLongName' => b.badge_name,
204
+ 'columnname' => nil,
205
+ 'columnnameLongName' => b.requirement_label,
206
+ 'data' => b.data,
207
+ 'section' => b.badge_section,
208
+ 'sectionLongName' => nil,
209
+ 'badgetype' => b.badge_type.to_s,
210
+ 'badgetypeLongName' => nil,
211
+ }
212
+ })
206
213
  }
207
214
  response = api.perform_query("programme.php?action=editEvening", api_data)
208
215
 
@@ -276,20 +283,11 @@ module Osm
276
283
  else
277
284
  # We'll have to iterate through the activities
278
285
  require_ability_to(api, :read, :programme, section_id, options)
279
- badges = []
286
+ badges = badge_links
280
287
  activities.each do |activity|
281
288
  activity = Osm::Activity.get(api, activity.activity_id, nil, options)
282
289
  activity.badges.each do |badge|
283
- badges.push ({
284
- 'name' => badge.label,
285
- 'badgeName' => badge.badge,
286
- 'sectionid' => section_id.to_s,
287
- 'eveningid' => id.to_s,
288
- 'section' => badge.section_type,
289
- 'badgetype' => badge.type,
290
- 'badge' => badge.badge,
291
- 'columnname' => badge.requirement,
292
- })
290
+ badges.push badge
293
291
  end
294
292
  end
295
293
  end
@@ -354,39 +352,54 @@ module Osm
354
352
  include ActiveModel::MassAssignmentSecurity if ActiveModel::VERSION::MAJOR < 4
355
353
  include ActiveAttr::Model
356
354
 
357
- # @!attribute [rw] badge_key
358
- # @return [String] the badge being done
359
355
  # @!attribute [rw] badge_type
360
356
  # @return [Symbol] the type of badge
361
- # @!attribute [rw] requirement_key
362
- # @return [String] the requirement being done
363
357
  # @!attribute [rw] badge_section
364
358
  # @return [Symbol] the section type that the badge belongs to
365
- # @!attribute [rw] label
366
- # @return [String] human firendly label for the badge and requirement
359
+ # @!attribute [rw] requirement_label
360
+ # @return [String] human firendly requirement label
361
+ # @!attribute [rw] data
362
+ # @return [String] what to put in the column when the badge records are updated
363
+ # @!attribute [rw] badge_name
364
+ # @return [String] the badge's name
365
+ # @!attribute [rw] badge_id
366
+ # @return [Fixnum] the badge's ID in OSM
367
+ # @!attribute [rw] badge_version
368
+ # @return [Fixnum] the version of the badge
369
+ # @!attribute [rw] requirement_id
370
+ # @return [Fixnum] the requirement's ID in OSM
367
371
 
368
- attribute :badge_key, :type => String
369
372
  attribute :badge_type, :type => Object
370
- attribute :requirement_key, :type => String
371
373
  attribute :badge_section, :type => Object
372
- attribute :label, :type => String
374
+ attribute :requirement_label, :type => String
375
+ attribute :data, :type => String
376
+ attribute :badge_name, :type => String
377
+ attribute :badge_id, :type => Integer
378
+ attribute :badge_version, :type => Integer
379
+ attribute :requirement_id, :type => Integer
373
380
 
374
381
  if ActiveModel::VERSION::MAJOR < 4
375
- attr_accessible :badge_key, :badge_type, :requirement_key, :badge_section, :label
382
+ attr_accessible :badge_type, :badge_section, :requirement_label, :data, :badge_name, :badge_id, :badge_version, :requirement_id
376
383
  end
377
384
 
378
- validates_presence_of :badge_key
379
- validates_format_of :requirement_key, :with => /\A[a-z]_\d{2}\Z/, :message => 'is not in the correct format (e.g. "a_01")'
385
+ validates_presence_of :badge_name
380
386
  validates_inclusion_of :badge_section, :in => [:beavers, :cubs, :scouts, :explorers, :staged]
381
387
  validates_inclusion_of :badge_type, :in => [:core, :staged, :activity, :challenge]
388
+ validates_numericality_of :badge_id, :only_integer=>true, :greater_than=>0
389
+ validates_numericality_of :badge_version, :only_integer=>true, :greater_than_or_equal_to=>0
390
+ validates_numericality_of :requirement_id, :only_integer=>true, :greater_than=>0, :allow_nil=>true
382
391
 
383
392
  # @!method initialize
384
393
  # Initialize a new Meeting::Activity
385
394
  # @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
386
395
 
387
- # Compare BadgeLink based on title then activity_id
396
+ # Compare BadgeLink based on section, type, badge_name, requirement_label, data
388
397
  def <=>(another)
389
- return self.label <=> another.try(:label)
398
+ [:badge_section, :badge_type, :badge_name, :requirement_label].each do |attribute|
399
+ result = self.try(:data) <=> another.try(:data)
400
+ return result unless result == 0
401
+ end
402
+ return self.try(:data) <=> another.try(:data)
390
403
  end
391
404
 
392
405
  end # Class Meeting::BadgeLink