class Osm::Event
Constants
- EXTRA_ATTRIBUTES
- LIST_ATTRIBUTES
- SORT_BY
Public Class Methods
Create an event in OSM If something goes wrong adding badges to OSM then the event returned will have been read from OSM @param [Osm::Api] api The api to use to make the request @return [Osm::Event, nil] the created event, nil if failed @raise [Osm::ObjectIsInvalid] If the Event
is invalid
# File lib/osm/event.rb, line 219 def self.create(api, parameters) require_ability_to(api, :write, :events, parameters[:section_id]) event = new(parameters) raise Osm::ObjectIsInvalid, 'event is invalid' unless event.valid? data = api.perform_query("events.php?action=addEvent§ionid=#{event.section_id}", { 'name' => event.name, 'location' => event.location, 'startdate' => event.start? ? event.start.strftime(Osm::OSM_DATE_FORMAT) : '', 'enddate' => event.finish? ? event.finish.strftime(Osm::OSM_DATE_FORMAT) : '', 'cost' => event.cost_tbc? ? '-1' : event.cost, 'notes' => event.notes, 'starttime' => event.start? ? event.start.strftime(Osm::OSM_TIME_FORMAT) : '', 'endtime' => event.finish? ? event.finish.strftime(Osm::OSM_TIME_FORMAT) : '', 'confdate' => event.confirm_by_date? ? event.confirm_by_date.strftime(Osm::OSM_DATE_FORMAT) : '', 'allowChanges' => event.allow_changes ? 'true' : 'false', 'disablereminders' => !event.reminders ? 'true' : 'false', 'attendancelimit' => event.attendance_limit, 'attendancereminder' => event.attendance_reminder, 'limitincludesleaders' => event.attendance_limit_includes_leaders ? 'true' : 'false', 'allowbooking' => event.allow_booking ? 'true' : 'false', }) if (data.is_a?(Hash) && data.has_key?('id')) event.id = data['id'].to_i # The cached events for the section will be out of date - remove them cache_delete(api, ['events', event.section_id]) # Add badge links to OSM badges_created = true event.badges.each do |badge| badges_created &= event.add_badge_link(api, badge) end if badges_created cache_write(api, ['event', event.id], event) return event else # Someting went wrong adding badges so return what OSM has return get(api, event.section_id, event.id) end else return nil end end
Get an event @param [Osm::Api] api The api to use to make the request @param [Osm::Section, Fixnum, to_i
] section The section (or its ID) to get the events for @param [Fixnum, to_i
] event_id The id of the event to get @!macro options_get @return [Osm::Event, nil] the event (or nil if it couldn't be found
# File lib/osm/event.rb, line 199 def self.get(api, section, event_id, options={}) require_ability_to(api, :read, :events, section, options) section_id = section.to_i event_id = event_id.to_i cache_key = ['event', event_id] if !options[:no_cache] && cache_exist?(api, cache_key) return cache_read(api, cache_key) end event_data = api.perform_query("events.php?action=getEvent§ionid=#{section_id}&eventid=#{event_id}") return self.new_event_from_data(event_data) end
Get events for a section @param [Osm::Api] api The api to use to make the request @param [Osm::Section, Fixnum, to_i
] section The section (or its ID) to get the events for @!macro options_get @option options [Boolean] :include_archived (optional) if true then archived events will also be returned @return [Array<Osm::Event>]
# File lib/osm/event.rb, line 109 def self.get_for_section(api, section, options={}) require_ability_to(api, :read, :events, section, options) section_id = section.to_i cache_key = ['events', section_id] events = nil if !options[:no_cache] && cache_exist?(api, cache_key) ids = cache_read(api, cache_key) events = get_from_ids(api, ids, 'event', section, options, :get_for_section) end if events.nil? data = api.perform_query("events.php?action=getEvents§ionid=#{section_id}&showArchived=true") events = Array.new ids = Array.new unless data['items'].nil? data['items'].map { |i| i['eventid'].to_i }.each do |event_id| event_data = api.perform_query("events.php?action=getEvent§ionid=#{section_id}&eventid=#{event_id}") files_data = api.perform_query("ext/uploads/events/?action=listAttachments§ionid=#{section_id}&eventid=#{event_id}") files = files_data.is_a?(Hash) ? files_data['files'] : files_data files = [] unless files.is_a?(Array) event = self.new_event_from_data(event_data) event.files = files events.push event ids.push event.id cache_write(api, ['event', event.id], event) end end cache_write(api, cache_key, ids) end return events if options[:include_archived] return events.reject do |event| event.archived? end end
Get event list for a section (not all details for each event) @param [Osm::Api] api The api to use to make the request @param [Osm::Section, Fixnum, to_i
] section The section (or its ID) to get the events for @!macro options_get @return [Array<Hash>]
# File lib/osm/event.rb, line 152 def self.get_list(api, section, options={}) require_ability_to(api, :read, :events, section, options) section_id = section.to_i cache_key = ['events_list', section_id] events_cache_key = ['events', section_id] events = nil unless options[:no_cache] # Try getting from cache if cache_exist?(api, cache_key) return cache_read(api, cache_key) end # Try generating from cached events if cache_exist?(api, events_cache_key) ids = cache_read(api, events_cache_key) events = get_from_ids(api, ids, 'event', section, options, :get_for_section).map do |e| e.attributes.symbolize_keys.select do |k,v| LIST_ATTRIBUTES.include?(k) end end end end # Fetch from OSM if events.nil? data = api.perform_query("events.php?action=getEvents§ionid=#{section_id}&showArchived=true") events = Array.new unless data['items'].nil? data['items'].map do |event_data| events.push(attributes_from_data(event_data)) end end end cache_write(api, cache_key, events) return events end
Private Class Methods
# File lib/osm/event.rb, line 524 def self.attributes_from_data(event_data) { :id => Osm::to_i_or_nil(event_data['eventid']), :section_id => Osm::to_i_or_nil(event_data['sectionid']), :name => event_data['name'], :start => Osm::make_datetime(event_data['startdate'], event_data['starttime']), :finish => Osm::make_datetime(event_data['enddate'], event_data['endtime']), :cost => event_data['cost'].eql?('-1') ? 'TBC' : event_data['cost'], :location => event_data['location'], :notes => event_data['notes'], :archived => event_data['archived'].eql?('1'), :public_notepad => event_data['publicnotes'], :confirm_by_date => Osm::parse_date(event_data['confdate']), :allow_changes => event_data['allowchanges'].eql?('1'), :reminders => !event_data['disablereminders'].eql?('1'), :attendance_limit => event_data['attendancelimit'].to_i, :attendance_limit_includes_leaders => event_data['limitincludesleaders'].eql?('1'), :attendance_reminder => event_data['attendancereminder'].to_i, :allow_booking => event_data['allowbooking'].eql?('1'), } end
# File lib/osm/event.rb, line 546 def self.new_event_from_data(event_data) event = Osm::Event.new(attributes_from_data(event_data)) event.notepad = event_data['notepad'] columns = [] config_raw = event_data['config'] config_raw = '[]' if config_raw.blank? column_data = ActiveSupport::JSON.decode(config_raw) column_data = [] unless column_data.is_a?(Array) column_data.each do |field| columns.push Column.new(:id => field['id'], :name => field['name'], :label => field['pL'], :parent_required => field['pR'].to_s.eql?('1'), :event => event) end event.columns = columns badges = [] badges_data = event_data['badgelinks'] badges_data = [] unless badges_data.is_a?(Array) badges_data.each do |field| badges.push BadgeLink.new( badge_type: field['badgetype'].to_sym, badge_section: field['section'].to_sym, requirement_id: field['column_id'], badge_name: field['badgeLongName'], requirement_label: field['columnnameLongName'], data: field['data'], badge_id: field['badge_id'], badge_version: field['badge_version'], ) end event.badges = badges return event end
Public Instance Methods
Add a badge link to the event in OSM @param [Osm::Api] api The api to use to make the request @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 @return [Boolean] whether the update succedded
# File lib/osm/event.rb, line 436 def add_badge_link(api, link) raise Osm::ObjectIsInvalid, 'link is invalid' unless link.valid? data = api.perform_query("ext/badges/records/index.php?action=linkBadgeToItem§ionid=#{section_id}", { 'section' => link.badge_section, 'sectionid' => section_id, 'type' => 'event', 'id' => id, 'badge_id' => link.badge_id, 'badge_version' => link.badge_version, 'column_id' => link.requirement_id.to_i.eql?(0) ? -2 : link.requirement_id, 'column_data' => link.data, 'new_column_name' => link.requirement_id.to_i.eql?(0) ? link.requirement_label : '', }) return (data.is_a?(Hash) && data['status']) end
Add a column to the event in OSM @param [Osm::Api] api The api to use to make the request @param [String] label The label for the field in OSM @param [String] name The label for the field in My.SCOUT (if this is blank then parents can't edit it) @param [Boolean] required Whether the parent is required to enter something @return [Boolean] whether the update succedded @raise [Osm::ArgumentIsInvalid] If the name is blank
# File lib/osm/event.rb, line 460 def add_column(api, name, label='', required=false) require_ability_to(api, :write, :events, section_id) raise Osm::ArgumentIsInvalid, 'name is invalid' if name.blank? data = api.perform_query("events.php?action=addColumn§ionid=#{section_id}&eventid=#{id}", { 'columnName' => name, 'parentLabel' => label, 'parentRequire' => (required ? 1 : 0), }) # The cached events for the section will be out of date - remove them cache_delete(api, ['events', section_id]) cache_delete(api, ['event', id]) cache_delete(api, ['event_attendance', id]) self.columns = self.class.new_event_from_data(data).columns return data.is_a?(Hash) && (data['eventid'].to_i == id) end
Whether the cost is zero @return [Boolean] whether the cost is zero
# File lib/osm/event.rb, line 510 def cost_free? cost.eql?('0.00') end
Whether the cost is to be confirmed @return [Boolean] whether the cost is TBC
# File lib/osm/event.rb, line 504 def cost_tbc? cost.eql?('TBC') end
Delete event from OSM @param [Osm::Api] api The api to use to make the request @return [Boolean] whether the delete succedded
# File lib/osm/event.rb, line 366 def delete(api) require_ability_to(api, :write, :events, section_id) data = api.perform_query("events.php?action=deleteEvent§ionid=#{section_id}&eventid=#{id}") if data.is_a?(Hash) && data['ok'] cache_delete(api, ['event', id]) return true end return false end
Get event attendance @param [Osm::Api] api The api to use to make the request @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 @!macro options_get @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned @return [Array<Osm::Event::Attendance>]
# File lib/osm/event.rb, line 385 def get_attendance(api, term=nil, options={}) require_ability_to(api, :read, :events, section_id, options) term_id = term.nil? ? Osm::Term.get_current_term_for_section(api, section_id).id : term.to_i cache_key = ['event_attendance', id, term_id] if !options[:no_cache] && cache_exist?(api, cache_key) return cache_read(api, cache_key) end data = api.perform_query("events.php?action=getEventAttendance&eventid=#{id}§ionid=#{section_id}&termid=#{term_id}") data = data['items'] || [] payment_values = { 'Manual' => :manual, 'Automatic' => :automatic, } attending_values = { 'Yes' => :yes, 'No' => :no, 'Invited' => :invited, 'Show in My.SCOUT' => :shown, 'Reserved' => :reserved, } attendance = [] data.each_with_index do |item, index| attendance.push Osm::Event::Attendance.new( :event => self, :member_id => Osm::to_i_or_nil(item['scoutid']), :grouping_id => Osm::to_i_or_nil(item['patrolid'].eql?('') ? nil : item['patrolid']), :first_name => item['firstname'], :last_name => item['lastname'], :date_of_birth => item['dob'].nil? ? nil : Osm::parse_date(item['dob'], :ignore_epoch => true), :attending => attending_values[item['attending']], :payment_control => payment_values[item['payment']], :fields => item.select { |key, value| key.to_s.match(/\Af_\d+\Z/) } .inject({}){ |h,(k,v)| h[k[2..-1].to_i] = v; h }, :payments => item.select { |key, value| key.to_s.match(/\Ap\d+\Z/) } .inject({}){ |h,(k,v)| h[k[1..-1].to_i] = v; h }, :row => index, ) end cache_write(api, cache_key, attendance) return attendance end
Whether thete is a limit on attendance for this event @return [Boolean] whether thete is a limit on attendance for this event
# File lib/osm/event.rb, line 482 def limited_attendance? (attendance_limit != 0) end
Get the number of spaces left for the event @param [Osm::Api] api The api to use to make the request @return [Fixnum, nil] the number of spaces left (nil if there is no attendance limit)
# File lib/osm/event.rb, line 497 def spaces(api) return nil unless limited_attendance? return attendance_limit - attendees(api) end
Whether there are spaces left for the event @param [Osm::Api] api The api to use to make the request @return [Boolean] whether there are spaces left for the event
# File lib/osm/event.rb, line 489 def spaces?(api) return true unless limited_attendance? return attendance_limit > attendees(api) end
Update event in OSM @param [Osm::Api] api The api to use to make the request @return [Boolean] whether the update succedded (will return true if no updates needed to be made)
# File lib/osm/event.rb, line 269 def update(api) require_ability_to(api, :write, :events, section_id) updated = true # Update main attributes update_main_attributes = false %w{ id name location start finish cost cost_tbc notes confirm_by_date allow_changes reminders attendance_limit attendance_limit_includes_leaders allow_booking }.each do |a| if changed_attributes.include?(a) update_main_attributes = true break # no use checking the others end end if update_main_attributes data = api.perform_query("events.php?action=addEvent§ionid=#{section_id}", { 'eventid' => id, 'name' => name, 'location' => location, 'startdate' => start? ? start.strftime(Osm::OSM_DATE_FORMAT) : '', 'enddate' => finish? ? finish.strftime(Osm::OSM_DATE_FORMAT) : '', 'cost' => cost_tbc? ? '-1' : cost, 'notes' => notes, 'starttime' => start? ? start.strftime(Osm::OSM_TIME_FORMAT) : '', 'endtime' => finish? ? finish.strftime(Osm::OSM_TIME_FORMAT) : '', 'confdate' => confirm_by_date? ? confirm_by_date.strftime(Osm::OSM_DATE_FORMAT) : '', 'allowChanges' => allow_changes ? 'true' : 'false', 'disablereminders' => !reminders ? 'true' : 'false', 'attendancelimit' => attendance_limit, 'attendancereminder' => attendance_reminder, 'limitincludesleaders' => attendance_limit_includes_leaders ? 'true' : 'false', 'allowbooking' => allow_booking ? 'true' : 'false', }) updated &= data.is_a?(Hash) && (data['id'].to_i == id) end # Private notepad if changed_attributes.include?('notepad') data = api.perform_query("events.php?action=saveNotepad§ionid=#{section_id}", { 'eventid' => id, 'notepad' => notepad, }) updated &= data.is_a?(Hash) end # MySCOUT notepad if changed_attributes.include?('public_notepad') data = api.perform_query("events.php?action=saveNotepad§ionid=#{section_id}", { 'eventid' => id, 'pnnotepad' => public_notepad, }) updated &= data.is_a?(Hash) end # Badges if changed_attributes.include?('badges') original_badges = @original_attributes['badges'] || [] # Deleted badges badges_to_delete = [] original_badges.each do |badge| unless badges.include?(badge) badges_to_delete.push badge end end badges_to_delete.each do |badge| data = api.perform_query("ext/badges/records/index.php?action=deleteBadgeLink§ionid=#{section_id}", { 'section' => badge.badge_section, 'sectionid' => section_id, 'type' => 'event', 'id' => id, 'badge_id' => badge.badge_id, 'badge_version' => badge.badge_version, 'column_id' => badge.requirement_id, }) updated &= data.is_a?(Hash) && data['status'] end # Added badges badges.each do |badge| unless original_badges.include?(badge) updated &= add_badge_link(api, badge) end end end # includes badges if updated reset_changed_attributes # The cached event will be out of date - remove it cache_delete(api, ['event', id]) return true else return false end end
Private Instance Methods
# File lib/osm/event.rb, line 516 def attendees(api) attendees = 0 get_attendance(api).each do |a| attendees += 1 unless attendance_limit_includes_leaders && (a.grouping_id == -2) end return attendees end