lib/osm/badge.rb in osm-1.2.1 vs lib/osm/badge.rb in osm-1.2.2
- old
+ new
@@ -280,10 +280,14 @@
validates_numericality_of :awarded, :only_integer=>true, :greater_than_or_equal_to=>0
validates_numericality_of :member_id, :only_integer=>true, :greater_than=>0
validates_numericality_of :section_id, :only_integer=>true, :greater_than=>0
validates :requirements, :hash => {:key_type => String, :value_type => String}
+ STAGES_NIGHTSAWAY = [1, 5, 10, 20, 35, 50, 75, 100, 125, 150, 175, 200]
+ STAGES_HIKESAWAY = [1, 5, 10, 20, 35, 50]
+
+
# @!method initialize
# Initialize a new Badge
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
# Override initialize to set @orig_attributes
old_initialize = instance_method(:initialize)
@@ -298,11 +302,11 @@
# Get the total number of gained requirements
# @return [Fixnum] the total number of requirements considered gained
def total_gained
count = 0
requirements.each do |field, data|
- next if data.blank? || data.to_s[0].downcase.eql?('x')
+ next unless reguiremet_met?(data)
count += 1
end
return count
end
@@ -312,11 +316,11 @@
required = badge.needed_from_section
gained = gained_in_sections
count = 0
required.each do |section, needed|
- next if gained[section] >= needed
+ next if gained[section] < needed
count += 1
end
return count
end
@@ -326,37 +330,74 @@
count = {}
requirements.each do |field, data|
field = field.split('_')[0]
unless field.eql?('y')
count[field] ||= 0
- next if data.blank? || data.to_s[0].downcase.eql?('x')
+ next unless reguiremet_met?(data)
count[field] += 1
else
# A total 'section'
- count['a'] = data.to_i
+ count['y'] = data.to_i
end
end
return count
end
- # Check if this badge is due
+ # Check if this badge is due (according data retrieved from OSM)
# @return [Boolean] whether the badge is due to the member
def due?
completed > awarded
end
+
+ # Check if this badge has been earnt
+ # @return [Boolean] whether the badge is due to the member
+ def earnt?
+ if badge.type == :staged
+ return (earnt > awarded)
+ end
+ return false if (completed.eql?(1) && awarded.eql?(1))
+ return true if (completed.eql?(1) && awarded.eql?(0))
+ return (total_gained >= badge.total_needed) && (sections_gained >= badge.sections_needed)
+ end
+
+ # Get what stage which has most recently been earnt
+ # (using #earnt? will tell you if it's still due (not yet awarded))
+ # @return [Fixnum] the stage which has most recently been due
+ def earnt
+ unless badge.type == :staged
+ return earnt? ? 1 : 0
+ end
+ if ['nightsaway', 'hikes'].include?(badge.osm_key)
+ total_done = requirements['y_01']
+ stages = STAGES_NIGHTSAWAY if badge.osm_key.eql?('nightsaway')
+ stages = STAGES_HIKESAWAY if badge.osm_key.eql?('hikes')
+ stages.reverse_each do |stage|
+ return stage if total_done >= stage
+ end
+ else
+ (awarded..5).reverse_each do |stage|
+ group = 'abcde'[stage - 1]
+ if gained_in_sections[group] >= badge.needed_from_section[group]
+ return stage
+ end
+ end
+ end
+ return 0
+ end
+
# Check if this badge has been started
# @return [Boolean] whether the badge has been started by the member (always false if the badge has been completed)
def started?
return (started > completed) if badge.type.eql?(:staged) # It's a staged badge
return false if completed?
requirements.each do |key, value|
case key.split('_')[0]
when 'a'
- return true unless value.blank? || value.to_s[0].downcase.eql?('x')
+ return true if reguiremet_met?(value)
when 'y'
- return true if (requirements['y_01'].to_i > 0)
+ return true if (value.to_i > 0)
end
end
return false
end
@@ -366,12 +407,12 @@
unless badge.type == :staged
return started? ? 1 : 0
else
# Staged badge
if ['nightsaway', 'hikes'].include?(badge.osm_key) # Special staged badges
- stages = [1, 5, 10, 20, 35, 50, 75, 100, 125, 150, 175, 200] if badge.osm_key.eql?('nightsaway')
- stages = [1, 5, 10, 20, 35, 50] if badge.osm_key.eql?('hikes')
+ stages = STAGES_NIGHTSAWAY if badge.osm_key.eql?('nightsaway')
+ stages = STAGES_HIKESAWAY if badge.osm_key.eql?('hikes')
done = requirements['y_01'].to_i
return 0 if done < stages[0] # Not started the first stage
return 0 if done >= stages[stages.size - 1] # No more stages can be started
(1..stages.size-1).reverse_each do |index|
if (done < stages[index]) && (done > stages[index-1])
@@ -489,9 +530,15 @@
return result
end
def inspect
Osm.inspect_instance(self, options={:replace_with => {'badge' => :osm_key}})
+ end
+
+ private
+ def reguiremet_met?(data)
+ return false if data == 0
+ !(data.blank? || data.to_s[0].downcase.eql?('x'))
end
end # Class Data
end # Class Badge