osm 1.2.14 → 1.2.15.dev

Sign up to get free protection for your applications and to get access to all the features.
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