Class: Osm::Badge::Data
Constant Summary collapse
- SORT_BY =
[:badge, :section_id, :member_id]
Instance Attribute Summary collapse
-
#awarded ⇒ Date
The last stage awarded.
-
#awarded_date ⇒ Date
When the badge was awarded.
-
#badge ⇒ Osm::Badge
The badge that the data belongs to.
-
#due ⇒ Fixnum
Whether this badge is due according to OSM, number indicates stage if appropriate.
-
#first_name ⇒ Fixnum
The member’s first name.
-
#last_name ⇒ Fixnum
The member’s last name.
-
#member_id ⇒ Fixnum
ID of the member this data relates to.
-
#requirements ⇒ DirtyHashy
The data for each badge requirement.
-
#section_id ⇒ Fixnum
The ID of the section the member belongs to.
Instance Method Summary collapse
-
#earnt ⇒ Fixnum
Get what stage which has most recently been earnt (using #earnt? will tell you if it’s still due (not yet awarded)).
-
#earnt? ⇒ Boolean
Check if this badge has been earnt.
-
#gained_in_modules ⇒ Hash
Get the number of requirements gained in each module.
- #inspect ⇒ Object
-
#mark_awarded(api, date = Date.today, level = due) ⇒ Boolean
Mark the badge as awarded in OSM.
-
#mark_due(api, level = earnt) ⇒ Boolean
Mark the badge as due in OSM.
-
#mark_not_awarded(api) ⇒ Boolean
Mark the badge as not awarded in OSM.
-
#mark_not_due(api) ⇒ Boolean
Mark the badge as not due in OSM.
-
#modules_gained ⇒ Array<Stirng>
Get the letters of modules gained.
-
#requirement_met?(requirement_id) ⇒ Boolean
Work out if the requirmeent has been met.
-
#started ⇒ Fixnum
Get which stage has been started.
-
#started? ⇒ Boolean
Check if this badge has been started.
-
#total_gained ⇒ Fixnum
Get the total number of gained requirements.
-
#update(api) ⇒ Boolean
Update data in OSM.
Methods inherited from Model
#<, #<=, #<=>, #>, #>=, #between?, #changed_attributes, configure, #reset_changed_attributes, #to_i
Instance Attribute Details
#awarded ⇒ Date
Returns the last stage awarded.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#awarded_date ⇒ Date
Returns when the badge was awarded.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#badge ⇒ Osm::Badge
Returns the badge that the data belongs to.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#due ⇒ Fixnum
Returns whether this badge is due according to OSM, number indicates stage if appropriate.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#first_name ⇒ Fixnum
Returns the member’s first name.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#last_name ⇒ Fixnum
Returns the member’s last name.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#member_id ⇒ Fixnum
Returns ID of the member this data relates to.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#requirements ⇒ DirtyHashy
Returns the data for each badge requirement.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
#section_id ⇒ Fixnum
Returns the ID of the section the member belongs to.
535 |
# File 'lib/osm/badge.rb', line 535 attribute :member_id, :type => Integer |
Instance Method Details
#earnt ⇒ Fixnum
Get what stage which has most recently been earnt (using #earnt? will tell you if it’s still due (not yet awarded))
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 |
# File 'lib/osm/badge.rb', line 654 def earnt unless badge.has_levels? return earnt? ? 1 : 0 end levels_column = badge.level_requirement unless badge.show_level_letters # It's a hikes, nights type badge badge.levels.reverse_each do |level| return level if requirements[levels_column].to_i >= level end else # It's an activity type badge modules = modules_gained letters = ('a'..'z').to_a (awarded..badge.levels.last).reverse_each do |level| return level if modules.include?(letters[level - 1]) end end return 0 end |
#earnt? ⇒ Boolean
Check if this badge has been earnt
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 |
# File 'lib/osm/badge.rb', line 614 def earnt? if badge.has_levels? return earnt > awarded else return false if (due.eql?(1) && awarded.eql?(1)) return true if (due.eql?(1) && awarded.eql?(0)) if badge.min_modules_required > 0 return false unless modules_gained.size >= badge.min_modules_required end if badge.min_requirements_required > 0 return false unless total_gained >= badge.min_requirements_required end if badge.requires_modules # [['a'], ['b', 'c']] = a and (b or c) requires = badge.requires_modules.clone modules = modules_gained requires.map!{ |a| a.map{ |b| modules.include?(b) } } # Replace letters with true/false requires.map!{ |a| a.include?(true) } # Replace each combination with true/false return false if requires.include?(false) # Only earnt if all combinations are met end badge.other_requirements_required.each do |c| # {:id => ###, :min => #} if requirements.has_key?(c[:id]) # Only check it if the data is in the requirements Hash return false unless requirement_met?(c[:id]) return false if requirements[c[:id]].to_i < c[:min] end end badge.badges_required.each do |b| # {:id => ###, :version => #} #TODO end return true end end |
#gained_in_modules ⇒ Hash
Get the number of requirements gained in each module
597 598 599 600 601 602 603 604 605 606 607 608 609 |
# File 'lib/osm/badge.rb', line 597 def gained_in_modules count = {} badge.modules.each do |mod| count[mod.id] ||= 0 count[mod.letter] ||= 0 end badge.requirements.each do |requirement| next unless requirement_met?(requirement.id) count[requirement.mod.id] += 1 count[requirement.mod.letter] += 1 end count end |
#inspect ⇒ Object
848 849 850 |
# File 'lib/osm/badge.rb', line 848 def inspect Osm.inspect_instance(self, {:replace_with => {'badge' => :name}}) end |
#mark_awarded(api, date = Date.today, level = due) ⇒ Boolean
Mark the badge as awarded in OSM
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
# File 'lib/osm/badge.rb', line 728 def mark_awarded(api, date=Date.today, level=due) raise ArgumentError, 'date is not a Date' unless date.is_a?(Date) raise ArgumentError, 'level can not be negative' if level < 0 section = Osm::Section.get(api, section_id) require_ability_to(api, :write, :badge, section) date_formatted = date.strftime(Osm::OSM_DATE_FORMAT) entries = [{ 'badge_id' => badge.id.to_s, 'badge_version' => badge.version.to_s, 'scout_id' => member_id.to_s, 'level' => level.to_s }] result = api.perform_query("ext/badges/records/?action=awardBadge", { 'date' => date_formatted, 'sectionid' => section_id, 'entries' => entries.to_json }) updated = result.is_a?(Hash) && (result['scoutid'].to_i == member_id) && (result['awarded'].to_i == level) && (result['awardeddate'] == date_formatted) if updated awarded = level awarded_date = date end return updated end |
#mark_due(api, level = earnt) ⇒ Boolean
Mark the badge as due in OSM
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 |
# File 'lib/osm/badge.rb', line 771 def mark_due(api, level=earnt) raise ArgumentError, 'level can not be negative' if level < 0 section = Osm::Section.get(api, section_id) require_ability_to(api, :write, :badge, section) result = api.perform_query("ext/badges/records/?action=overrideCompletion", { 'section_id' => section.id, 'badge_id' => badge.id, 'badge_version' => badge.version, 'scoutid' => member_id, 'level' => level }) updated = result.is_a?(Hash) && (result['scoutid'].to_i == member_id) && (result['completed'].to_i == level) return updated end |
#mark_not_awarded(api) ⇒ Boolean
Mark the badge as not awarded in OSM
762 763 764 |
# File 'lib/osm/badge.rb', line 762 def mark_not_awarded(api) mark_awarded(api, Date.today, 0) end |
#mark_not_due(api) ⇒ Boolean
Mark the badge as not due in OSM
792 793 794 |
# File 'lib/osm/badge.rb', line 792 def mark_not_due(api) mark_due(api, 0) end |
#modules_gained ⇒ Array<Stirng>
Get the letters of modules gained
585 586 587 588 589 590 591 592 593 |
# File 'lib/osm/badge.rb', line 585 def modules_gained g_i_m = gained_in_modules gained = [] badge.modules.each do |mod| next if g_i_m[mod.id] < mod.min_required gained.push mod.letter end gained end |
#requirement_met?(requirement_id) ⇒ Boolean
Work out if the requirmeent has been met
855 856 857 858 859 |
# File 'lib/osm/badge.rb', line 855 def requirement_met?(requirement_id) data = requirements[requirement_id.to_i].to_s return false if data == '0' !(data.blank? || data[0].downcase.eql?('x')) end |
#started ⇒ Fixnum
Get which stage has been started
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 |
# File 'lib/osm/badge.rb', line 691 def started unless badge.has_levels? return started? ? 1 : 0 end unless badge.show_level_letters # Nights, Hikes or Water done = requirements[badge.level_requirement].to_i levels = badge.levels # e.g. [0,1,2,3,4,5,10] return 0 if levels.include?(done) # Has achieved a level (and not started next ) return 0 if done >= levels[-1] # No more levels to do (1..(levels.size-1)).to_a.reverse_each do |i| # indexes from last to 2nd this_level = levels[i] previous_level = levels[i-1] return this_level if (done < this_level && done > previous_level) # this_level has been started (and not finished) end return 0 # No reason we should ever get here else # 'Normal' staged letters = ('a'..'z').to_a top_level = badge.levels[-1] return 0 if due == top_level || awarded == top_level # No more levels to do ((due + 1)..top_level).reverse_each do |level| badge.requirements.each do |requirement| next unless requirement.mod.letter.eql?(letters[level - 1]) # Not interested in other levels return level if requirement_met?(requirement.id) end end return 0 # No levels started end end |
#started? ⇒ Boolean
Check if this badge has been started
677 678 679 680 681 682 683 684 685 686 |
# File 'lib/osm/badge.rb', line 677 def started? if badge.has_levels? return (started > due) end return false if due? requirements.each do |key, value| return true if requirement_met?(key) end return false end |
#total_gained ⇒ Fixnum
Get the total number of gained requirements
574 575 576 577 578 579 580 581 |
# File 'lib/osm/badge.rb', line 574 def total_gained count = 0 badge.requirements.each do |requirement| next unless requirement_met?(requirement.id) count += 1 end return count end |
#update(api) ⇒ Boolean
Update data in OSM
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 |
# File 'lib/osm/badge.rb', line 800 def update(api) raise Osm::ObjectIsInvalid, 'data is invalid' unless valid? section = Osm::Section.get(api, section_id) require_ability_to(api, :write, :badge, section) # Update requirements that changed requirements_updated = true editable_requirements = badge.requirements.select{ |r| r.editable }.map{ |r| r.id } requirements.changes.each do |requirement, (was,now)| if editable_requirements.include?(requirement) result = api.perform_query("ext/badges/records/?action=updateSingleRecord", { 'scoutid' => member_id, 'section_id' => section_id, 'badge_id' => badge.id, 'badge_version' => badge.version, 'field' => requirement, 'value' => now }) requirements_updated = false unless result.is_a?(Hash) && (result['scoutid'].to_i == member_id) && (result[requirement.to_s].to_s == now.to_s) end end if requirements_updated requirements.clean_up! end # Update due if it changed due_updated = true if changed_attributes.include?('due') due_updated = mark_due(api, due) end # Update awarded if it changed awarded_updated = true if changed_attributes.include?('awarded') || changed_attributes.include?('awarded_date') awarded_updated = mark_awarded(api, awarded_date, awarded) end # reset changed attributes if everything was updated ok if due_updated && awarded_updated reset_changed_attributes end return requirements_updated && due_updated && awarded_updated end |