osm 0.1.17 → 0.2.0
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/CHANGELOG.md +45 -0
- data/Guardfile +9 -0
- data/README.md +15 -13
- data/lib/osm.rb +14 -0
- data/lib/osm/activity.rb +44 -13
- data/lib/osm/api.rb +48 -12
- data/lib/osm/api_access.rb +9 -6
- data/lib/osm/due_badges.rb +5 -4
- data/lib/osm/event.rb +87 -107
- data/lib/osm/flexi_record.rb +159 -118
- data/lib/osm/grouping.rb +41 -2
- data/lib/osm/{evening.rb → meeting.rb} +71 -64
- data/lib/osm/member.rb +88 -68
- data/lib/osm/model.rb +120 -30
- data/lib/osm/register.rb +23 -14
- data/lib/osm/section.rb +40 -100
- data/lib/osm/term.rb +35 -24
- data/osm.gemspec +2 -0
- data/spec/osm/activity_spec.rb +190 -173
- data/spec/osm/api_access_spec.rb +15 -7
- data/spec/osm/api_spec.rb +54 -27
- data/spec/osm/event_spec.rb +95 -84
- data/spec/osm/flexi_record_spec.rb +138 -35
- data/spec/osm/grouping_spec.rb +59 -1
- data/spec/osm/{evening_spec.rb → meeting_spec.rb} +53 -53
- data/spec/osm/member_spec.rb +151 -45
- data/spec/osm/model_spec.rb +28 -34
- data/spec/osm/register_spec.rb +1 -1
- data/spec/osm/section_spec.rb +49 -82
- data/spec/osm/term_spec.rb +23 -15
- data/spec/spec_helper.rb +25 -0
- data/version.rb +1 -1
- metadata +41 -18
    
        data/lib/osm/event.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            module Osm
         | 
| 2 2 |  | 
| 3 3 | 
             
              class Event < Osm::Model
         | 
| 4 | 
            -
                class Column; end # Ensure the constant exists for the validators
         | 
| 4 | 
            +
                class Column < Osm::Model; end # Ensure the constant exists for the validators
         | 
| 5 5 |  | 
| 6 6 | 
             
                # @!attribute [rw] id
         | 
| 7 7 | 
             
                #   @return [Fixnum] the id for the event
         | 
| @@ -21,9 +21,6 @@ module Osm | |
| 21 21 | 
             
                #   @return [String] notes about the event
         | 
| 22 22 | 
             
                # @!attribute [rw] archived
         | 
| 23 23 | 
             
                #   @return [Boolean] if the event has been archived
         | 
| 24 | 
            -
                # @!attribute [rw] fields
         | 
| 25 | 
            -
                #   @deprecated use columns instead
         | 
| 26 | 
            -
                #   @return [Hash] Keys are the field's id, values are the field names
         | 
| 27 24 | 
             
                # @!attribute [rw] columns
         | 
| 28 25 | 
             
                #   @return [Array<Osm::Event::Column>] the custom columns for the event
         | 
| 29 26 | 
             
                # @!attribute [rw] notepad
         | 
| @@ -75,36 +72,41 @@ module Osm | |
| 75 72 |  | 
| 76 73 | 
             
                # @!method initialize
         | 
| 77 74 | 
             
                #   Initialize a new Event
         | 
| 78 | 
            -
                #   @param [Hash] attributes  | 
| 75 | 
            +
                #   @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
         | 
| 79 76 |  | 
| 80 77 |  | 
| 81 78 | 
             
                # Get events for a section
         | 
| 82 79 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 83 | 
            -
                # @param [Osm::Section, Fixnum] section  | 
| 80 | 
            +
                # @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the events for
         | 
| 84 81 | 
             
                # @!macro options_get
         | 
| 85 82 | 
             
                # @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
         | 
| 86 83 | 
             
                # @return [Array<Osm::Event>]
         | 
| 87 84 | 
             
                def self.get_for_section(api, section, options={})
         | 
| 85 | 
            +
                  require_ability_to(api, :read, :events, section, options)
         | 
| 88 86 | 
             
                  section_id = section.to_i
         | 
| 89 87 | 
             
                  cache_key = ['events', section_id]
         | 
| 90 88 | 
             
                  events = nil
         | 
| 91 89 |  | 
| 92 | 
            -
                  if !options[:no_cache] && cache_exist?(api, cache_key) | 
| 93 | 
            -
                     | 
| 90 | 
            +
                  if !options[:no_cache] && cache_exist?(api, cache_key)
         | 
| 91 | 
            +
                    ids = cache_read(api, cache_key)
         | 
| 92 | 
            +
                    events = get_from_ids(api, ids, 'event', section, options, :get_for_section)
         | 
| 94 93 | 
             
                  end
         | 
| 95 94 |  | 
| 96 | 
            -
                   | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
                    data['items']. | 
| 101 | 
            -
                       | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 95 | 
            +
                  if events.nil?
         | 
| 96 | 
            +
                    data = api.perform_query("events.php?action=getEvents§ionid=#{section_id}&showArchived=true")
         | 
| 97 | 
            +
                    events = Array.new
         | 
| 98 | 
            +
                    ids = Array.new
         | 
| 99 | 
            +
                    unless data['items'].nil?
         | 
| 100 | 
            +
                      data['items'].map { |i| i['eventid'].to_i }.each do |event_id|
         | 
| 101 | 
            +
                        event_data = api.perform_query("events.php?action=getEvent§ionid=#{section_id}&eventid=#{event_id}")
         | 
| 102 | 
            +
                        event = self.new_event_from_data(event_data)
         | 
| 103 | 
            +
                        events.push event
         | 
| 104 | 
            +
                        ids.push event.id
         | 
| 105 | 
            +
                        cache_write(api, ['event', event.id], event)
         | 
| 106 | 
            +
                      end
         | 
| 105 107 | 
             
                    end
         | 
| 108 | 
            +
                    cache_write(api, cache_key, ids)
         | 
| 106 109 | 
             
                  end
         | 
| 107 | 
            -
                  cache_write(api, cache_key, events)
         | 
| 108 110 |  | 
| 109 111 | 
             
                  return events if options[:include_archived]
         | 
| 110 112 | 
             
                  return events.reject do |event|
         | 
| @@ -114,16 +116,17 @@ module Osm | |
| 114 116 |  | 
| 115 117 | 
             
                # Get an event
         | 
| 116 118 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 117 | 
            -
                # @param [Osm::Section, Fixnum] section  | 
| 118 | 
            -
                # @param [Fixnum] event_id  | 
| 119 | 
            +
                # @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the events for
         | 
| 120 | 
            +
                # @param [Fixnum] event_id The id of the event to get
         | 
| 119 121 | 
             
                # @!macro options_get
         | 
| 120 122 | 
             
                # @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
         | 
| 121 123 | 
             
                # @return [Osm::Event, nil] the event (or nil if it couldn't be found
         | 
| 122 124 | 
             
                def self.get(api, section, event_id, options={})
         | 
| 125 | 
            +
                  require_ability_to(api, :read, :events, section, options)
         | 
| 123 126 | 
             
                  section_id = section.to_i
         | 
| 124 127 | 
             
                  cache_key = ['event', event_id]
         | 
| 125 128 |  | 
| 126 | 
            -
                  if !options[:no_cache] && cache_exist?(api, cache_key) | 
| 129 | 
            +
                  if !options[:no_cache] && cache_exist?(api, cache_key)
         | 
| 127 130 | 
             
                    return cache_read(api, cache_key)
         | 
| 128 131 | 
             
                  end
         | 
| 129 132 |  | 
| @@ -135,10 +138,11 @@ module Osm | |
| 135 138 | 
             
                # Create an event in OSM
         | 
| 136 139 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 137 140 | 
             
                # @return [Osm::Event, nil] the created event, nil if failed
         | 
| 141 | 
            +
                # @raise [Osm::ObjectIsInvalid] If the Event is invalid
         | 
| 138 142 | 
             
                def self.create(api, parameters)
         | 
| 143 | 
            +
                  require_ability_to(api, :write, :events, parameters[:section_id])
         | 
| 139 144 | 
             
                  event = new(parameters)
         | 
| 140 | 
            -
                  raise ObjectIsInvalid, 'event is invalid' unless event.valid?
         | 
| 141 | 
            -
                  raise Forbidden, 'you do not have permission to write to events for this section' unless get_user_permission(api, event.section_id, :events).include?(:write)
         | 
| 145 | 
            +
                  raise Osm::ObjectIsInvalid, 'event is invalid' unless event.valid?
         | 
| 142 146 |  | 
| 143 147 | 
             
                  data = api.perform_query("events.php?action=addEvent§ionid=#{event.section_id}", {
         | 
| 144 148 | 
             
                    'name' => event.name,
         | 
| @@ -172,7 +176,9 @@ module Osm | |
| 172 176 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 173 177 | 
             
                # @return [Boolean] whether the update succedded
         | 
| 174 178 | 
             
                def update(api)
         | 
| 175 | 
            -
                   | 
| 179 | 
            +
                  require_ability_to(api, :write, :events, section_id)
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                  to_update = changed_attributes
         | 
| 176 182 |  | 
| 177 183 | 
             
                  data = api.perform_query("events.php?action=addEvent§ionid=#{section_id}", {
         | 
| 178 184 | 
             
                    'eventid' => id,
         | 
| @@ -190,49 +196,55 @@ module Osm | |
| 190 196 | 
             
                    'attendancelimit' => attendance_limit,
         | 
| 191 197 | 
             
                    'limitincludesleaders' => attendance_limit_includes_leaders,
         | 
| 192 198 | 
             
                  })
         | 
| 199 | 
            +
             | 
| 193 200 | 
             
                  api.perform_query("events.php?action=saveNotepad§ionid=#{section_id}", {
         | 
| 194 201 | 
             
                    'eventid' => id,
         | 
| 195 202 | 
             
                    'notepad' => notepad,
         | 
| 196 | 
            -
                  })
         | 
| 203 | 
            +
                  }) if to_update.include?('notepad')
         | 
| 204 | 
            +
             | 
| 197 205 | 
             
                  api.perform_query("events.php?action=saveNotepad§ionid=#{section_id}", {
         | 
| 198 206 | 
             
                    'eventid' => id,
         | 
| 199 207 | 
             
                    'pnnotepad' => public_notepad,
         | 
| 200 | 
            -
                  })
         | 
| 201 | 
            -
             | 
| 202 | 
            -
                  # The cached events for the section will be out of date - remove them
         | 
| 203 | 
            -
                  cache_delete(api, ['event', id])
         | 
| 204 | 
            -
                  cache_delete(api, ['events', section_id])
         | 
| 208 | 
            +
                  }) if to_update.include?('public_notepad')
         | 
| 205 209 |  | 
| 206 | 
            -
                   | 
| 210 | 
            +
                  if data.is_a?(Hash) && (data['id'].to_i == id)
         | 
| 211 | 
            +
                    reset_changed_attributes
         | 
| 212 | 
            +
                    # The cached event will be out of date - remove it
         | 
| 213 | 
            +
                    cache_delete(api, ['event', id])
         | 
| 214 | 
            +
                    return true
         | 
| 215 | 
            +
                  else
         | 
| 216 | 
            +
                    return false
         | 
| 217 | 
            +
                  end
         | 
| 207 218 | 
             
                end
         | 
| 208 219 |  | 
| 209 220 | 
             
                # Delete event from OSM
         | 
| 210 221 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 211 222 | 
             
                # @return [Boolean] whether the delete succedded
         | 
| 212 223 | 
             
                def delete(api)
         | 
| 213 | 
            -
                   | 
| 224 | 
            +
                  require_ability_to(api, :write, :events, section_id)
         | 
| 214 225 |  | 
| 215 226 | 
             
                  data = api.perform_query("events.php?action=deleteEvent§ionid=#{section_id}&eventid=#{id}")
         | 
| 216 227 |  | 
| 217 | 
            -
                   | 
| 218 | 
            -
             | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
                  return  | 
| 228 | 
            +
                  if data.is_a?(Hash) && data['ok']
         | 
| 229 | 
            +
                    cache_delete(api, ['event', id])
         | 
| 230 | 
            +
                    return true
         | 
| 231 | 
            +
                  end
         | 
| 232 | 
            +
                  return false
         | 
| 222 233 | 
             
                end
         | 
| 223 234 |  | 
| 224 235 |  | 
| 225 236 | 
             
                # Get event attendance
         | 
| 226 237 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 227 | 
            -
                # @param [Osm::Term, Fixnum, nil] term  | 
| 238 | 
            +
                # @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
         | 
| 228 239 | 
             
                # @!macro options_get
         | 
| 229 240 | 
             
                # @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
         | 
| 230 241 | 
             
                # @return [Array<Osm::Event::Attendance>]
         | 
| 231 242 | 
             
                def get_attendance(api, term=nil, options={})
         | 
| 243 | 
            +
                  require_ability_to(api, :read, :events, section_id, options)
         | 
| 232 244 | 
             
                  term_id = term.nil? ? Osm::Term.get_current_term_for_section(api, section_id).id : term.to_i
         | 
| 233 245 | 
             
                  cache_key = ['event_attendance', id]
         | 
| 234 246 |  | 
| 235 | 
            -
                  if !options[:no_cache] && cache_exist?(api, cache_key) | 
| 247 | 
            +
                  if !options[:no_cache] && cache_exist?(api, cache_key)
         | 
| 236 248 | 
             
                    return cache_read(api, cache_key)
         | 
| 237 249 | 
             
                  end
         | 
| 238 250 |  | 
| @@ -264,12 +276,13 @@ module Osm | |
| 264 276 |  | 
| 265 277 | 
             
                # Add a column to the event in OSM
         | 
| 266 278 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 267 | 
            -
                # @param [String] label  | 
| 268 | 
            -
                # @param [String] name  | 
| 279 | 
            +
                # @param [String] label The label for the field in OSM
         | 
| 280 | 
            +
                # @param [String] name The label for the field in My.SCOUT (if this is blank then parents can't edit it)
         | 
| 269 281 | 
             
                # @return [Boolean] whether the update succedded
         | 
| 282 | 
            +
                # @raise [Osm::ArgumentIsInvalid] If the name is blank
         | 
| 270 283 | 
             
                def add_column(api, name, label='')
         | 
| 271 | 
            -
                   | 
| 272 | 
            -
                  raise  | 
| 284 | 
            +
                  require_ability_to(api, :write, :events, section_id)
         | 
| 285 | 
            +
                  raise Osm::ArgumentIsInvalid, 'name is invalid' if name.blank?
         | 
| 273 286 |  | 
| 274 287 | 
             
                  data = api.perform_query("events.php?action=addColumn§ionid=#{section_id}&eventid=#{id}", {
         | 
| 275 288 | 
             
                    'columnName' => name,
         | 
| @@ -286,41 +299,8 @@ module Osm | |
| 286 299 | 
             
                  return data.is_a?(Hash) && (data['eventid'].to_i == id)
         | 
| 287 300 | 
             
                end
         | 
| 288 301 |  | 
| 289 | 
            -
                #  | 
| 290 | 
            -
                # @ | 
| 291 | 
            -
                # @param [Osm::Api] api The api to use to make the request
         | 
| 292 | 
            -
                # @param [String] field_label the label for the field to add
         | 
| 293 | 
            -
                # @return [Boolean] whether the update succedded
         | 
| 294 | 
            -
                # TODO - Remove this method when upping the version
         | 
| 295 | 
            -
                def add_field(api, label)
         | 
| 296 | 
            -
                  warn "[DEPRECATION OF METHOD] this method is being depreiated, use add_column instead"
         | 
| 297 | 
            -
                  raise ArgumentIsInvalid, 'label is invalid' if label.blank?
         | 
| 298 | 
            -
                  raise Forbidden, 'you do not have permission to write to events for this section' unless get_user_permission(api, section_id, :events).include?(:write)
         | 
| 299 | 
            -
             | 
| 300 | 
            -
                  data = api.perform_query("events.php?action=addColumn§ionid=#{section_id}&eventid=#{id}", {
         | 
| 301 | 
            -
                    'columnName' => label,
         | 
| 302 | 
            -
                    'parentLabel' => ''
         | 
| 303 | 
            -
                  })
         | 
| 304 | 
            -
             | 
| 305 | 
            -
                  # The cached events for the section will be out of date - remove them
         | 
| 306 | 
            -
                  cache_delete(api, ['events', section_id])
         | 
| 307 | 
            -
                  cache_delete(api, ['event', id])
         | 
| 308 | 
            -
                  cache_delete(api, ['event_attendance', id])
         | 
| 309 | 
            -
             | 
| 310 | 
            -
                  return data.is_a?(Hash) && (data['eventid'].to_i == id)
         | 
| 311 | 
            -
                end
         | 
| 312 | 
            -
             | 
| 313 | 
            -
             | 
| 314 | 
            -
                # TODO - Remove this attribute when upping the version
         | 
| 315 | 
            -
                def fields
         | 
| 316 | 
            -
                  warn "[DEPRECATION OF ATTRIBUTE] this attribute is being depreiated, in favor of returning an array of Field objects."
         | 
| 317 | 
            -
                  return columns.inject({}){ |h,(c)| h[c.id] = c.name; h}
         | 
| 318 | 
            -
                end
         | 
| 319 | 
            -
                def fields=(value)
         | 
| 320 | 
            -
                  raise "[DEPRECATION OF ATTRIBUTE] this attribute is being depreiated, in favor of returning an array of Field objects."
         | 
| 321 | 
            -
                end
         | 
| 322 | 
            -
             | 
| 323 | 
            -
             | 
| 302 | 
            +
                # Whether thete is a limit on attendance for this event
         | 
| 303 | 
            +
                # @return [Boolean] whether thete is a limit on attendance for this event
         | 
| 324 304 | 
             
                def limited_attendance?
         | 
| 325 305 | 
             
                  (attendance_limit != 0)
         | 
| 326 306 | 
             
                end
         | 
| @@ -380,10 +360,7 @@ module Osm | |
| 380 360 | 
             
                end
         | 
| 381 361 |  | 
| 382 362 |  | 
| 383 | 
            -
                class Column
         | 
| 384 | 
            -
                  include ::ActiveAttr::MassAssignmentSecurity
         | 
| 385 | 
            -
                  include ::ActiveAttr::Model
         | 
| 386 | 
            -
              
         | 
| 363 | 
            +
                class Column < Osm::Model
         | 
| 387 364 | 
             
                  # @!attribute [rw] id
         | 
| 388 365 | 
             
                  #   @return [String] OSM id for the column
         | 
| 389 366 | 
             
                  # @!attribute [rw] name
         | 
| @@ -406,14 +383,14 @@ module Osm | |
| 406 383 |  | 
| 407 384 | 
             
                  # @!method initialize
         | 
| 408 385 | 
             
                  #   Initialize a new Column
         | 
| 409 | 
            -
                  #   @param [Hash] attributes  | 
| 386 | 
            +
                  #   @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
         | 
| 410 387 |  | 
| 411 388 |  | 
| 412 389 | 
             
                  # Update event column in OSM
         | 
| 413 390 | 
             
                  # @param [Osm::Api] api The api to use to make the request
         | 
| 414 391 | 
             
                  # @return [Boolean] if the operation suceeded or not
         | 
| 415 392 | 
             
                  def update(api)
         | 
| 416 | 
            -
                     | 
| 393 | 
            +
                    require_ability_to(api, :write, :events, event.section_id)
         | 
| 417 394 |  | 
| 418 395 | 
             
                    data = api.perform_query("events.php?action=renameColumn§ionid=#{event.section_id}&eventid=#{event.id}", {
         | 
| 419 396 | 
             
                      'columnId' => id,
         | 
| @@ -421,13 +398,16 @@ module Osm | |
| 421 398 | 
             
                      'pL' => label
         | 
| 422 399 | 
             
                    })
         | 
| 423 400 |  | 
| 424 | 
            -
                    # The cached events for the section will be out of date - remove them
         | 
| 425 | 
            -
                    Osm::Model.cache_delete(api, ['events', event.section_id])
         | 
| 426 | 
            -
                    Osm::Model.cache_delete(api, ['event', event.id])
         | 
| 427 | 
            -
             | 
| 428 401 | 
             
                    (ActiveSupport::JSON.decode(data['config']) || []).each do |i|
         | 
| 429 402 | 
             
                      if i['id'] == id
         | 
| 430 | 
            -
                         | 
| 403 | 
            +
                        if i['name'].eql?(name) && (i['pL'].nil? || i['pL'].eql?(label))
         | 
| 404 | 
            +
                          reset_changed_attributes
         | 
| 405 | 
            +
                            # The cached event will be out of date - remove it
         | 
| 406 | 
            +
                            cache_delete(api, ['event', event.id])
         | 
| 407 | 
            +
                            # The cached event attedance will be out of date
         | 
| 408 | 
            +
                            cache_delete(api, ['event_attendance', event.id])
         | 
| 409 | 
            +
                          return true
         | 
| 410 | 
            +
                        end
         | 
| 431 411 | 
             
                      end
         | 
| 432 412 | 
             
                    end
         | 
| 433 413 | 
             
                    return false
         | 
| @@ -437,16 +417,12 @@ module Osm | |
| 437 417 | 
             
                  # @param [Osm::Api] api The api to use to make the request
         | 
| 438 418 | 
             
                  # @return [Boolean] whether the delete succedded
         | 
| 439 419 | 
             
                  def delete(api)
         | 
| 440 | 
            -
                     | 
| 420 | 
            +
                    require_ability_to(api, :write, :events, event.section_id)
         | 
| 441 421 |  | 
| 442 422 | 
             
                    data = api.perform_query("events.php?action=deleteColumn§ionid=#{event.section_id}&eventid=#{event.id}", {
         | 
| 443 423 | 
             
                      'columnId' => id
         | 
| 444 424 | 
             
                    })
         | 
| 445 425 |  | 
| 446 | 
            -
                    # The cached events for the section will be out of date - remove them
         | 
| 447 | 
            -
                    Osm::Model.cache_delete(api, ['events', event.section_id])
         | 
| 448 | 
            -
                    Osm::Model.cache_delete(api, ['event', event.id])
         | 
| 449 | 
            -
             | 
| 450 426 | 
             
                    (ActiveSupport::JSON.decode(data['config']) || []).each do |i|
         | 
| 451 427 | 
             
                      return false if i['id'] == id
         | 
| 452 428 | 
             
                    end
         | 
| @@ -456,16 +432,15 @@ module Osm | |
| 456 432 | 
             
                      new_columns.push(column) unless column == self
         | 
| 457 433 | 
             
                    end
         | 
| 458 434 | 
             
                    event.columns = new_columns
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                    cache_write(api, ['event', event.id], event)
         | 
| 459 437 | 
             
                    return true
         | 
| 460 438 | 
             
                  end
         | 
| 461 439 |  | 
| 462 440 | 
             
                end # class Column
         | 
| 463 441 |  | 
| 464 442 |  | 
| 465 | 
            -
                class Attendance
         | 
| 466 | 
            -
                  include ::ActiveAttr::MassAssignmentSecurity
         | 
| 467 | 
            -
                  include ::ActiveAttr::Model
         | 
| 468 | 
            -
              
         | 
| 443 | 
            +
                class Attendance < Osm::Model  
         | 
| 469 444 | 
             
                  # @!attribute [rw] member_id
         | 
| 470 445 | 
             
                  #   @return [Fixnum] OSM id for the member
         | 
| 471 446 | 
             
                  # @!attribute [rw] grouping__id
         | 
| @@ -496,16 +471,17 @@ module Osm | |
| 496 471 |  | 
| 497 472 | 
             
                  # @!method initialize
         | 
| 498 473 | 
             
                  #   Initialize a new Attendance
         | 
| 499 | 
            -
                  #   @param [Hash] attributes  | 
| 474 | 
            +
                  #   @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
         | 
| 500 475 |  | 
| 501 476 |  | 
| 502 477 | 
             
                  # Update event attendance
         | 
| 503 478 | 
             
                  # @param [Osm::Api] api The api to use to make the request
         | 
| 504 | 
            -
                  # @param [String] field_id  | 
| 479 | 
            +
                  # @param [String] field_id The id of the field to update (must be 'attending' or /\Af_\d+\Z/)
         | 
| 505 480 | 
             
                  # @return [Boolean] if the operation suceeded or not
         | 
| 481 | 
            +
                  # @raise [Osm::ArgumentIsInvalid] If field_id does not match the pattern "f_#{number}" or is "attending"
         | 
| 506 482 | 
             
                  def update(api, field_id)
         | 
| 507 | 
            -
                     | 
| 508 | 
            -
                    raise  | 
| 483 | 
            +
                    require_ability_to(api, :write, :events, event.section_id)
         | 
| 484 | 
            +
                    raise Osm::ArgumentIsInvalid, 'field_id is invalid' unless field_id.match(/\Af_\d+\Z/) || field_id.eql?('attending')
         | 
| 509 485 |  | 
| 510 486 | 
             
                    data = api.perform_query("events.php?action=updateScout", {
         | 
| 511 487 | 
             
                      'scoutid' => member_id,
         | 
| @@ -515,11 +491,15 @@ module Osm | |
| 515 491 | 
             
                      'row' => row,
         | 
| 516 492 | 
             
                      'eventid' => event.id,
         | 
| 517 493 | 
             
                    })
         | 
| 518 | 
            -
             | 
| 519 | 
            -
                     | 
| 520 | 
            -
             | 
| 521 | 
            -
             | 
| 522 | 
            -
             | 
| 494 | 
            +
                
         | 
| 495 | 
            +
                    if data.is_a?(Hash)
         | 
| 496 | 
            +
                      reset_changed_attributes
         | 
| 497 | 
            +
                      # The cached event attedance will be out of date
         | 
| 498 | 
            +
                      Osm::Model.cache_delete(api, ['event_attendance', event.id])
         | 
| 499 | 
            +
                      return true
         | 
| 500 | 
            +
                    else
         | 
| 501 | 
            +
                      return false
         | 
| 502 | 
            +
                    end
         | 
| 523 503 | 
             
                  end
         | 
| 524 504 |  | 
| 525 505 | 
             
                end # Class Attendance
         | 
    
        data/lib/osm/flexi_record.rb
    CHANGED
    
    | @@ -1,32 +1,46 @@ | |
| 1 | 
            -
            # TODO make 'proper' class
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module Osm
         | 
| 4 2 |  | 
| 5 | 
            -
              class FlexiRecord
         | 
| 3 | 
            +
              class FlexiRecord < Osm::Model
         | 
| 4 | 
            +
                # @!attribute [rw] id
         | 
| 5 | 
            +
                #   @return [Fixnum] the id for the flexi_record
         | 
| 6 | 
            +
                # @!attribute [rw] section_id
         | 
| 7 | 
            +
                #   @return [Fixnum] the section the member belongs to
         | 
| 8 | 
            +
                # @!attribute [rw] name
         | 
| 9 | 
            +
                #   @return [String] the flexi record's name name
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                attribute :id, :type => Integer
         | 
| 12 | 
            +
                attribute :section_id, :type => Integer
         | 
| 13 | 
            +
                attribute :name, :type => String
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                attr_accessible :id, :section_id, :name
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                validates_numericality_of :id, :only_integer=>true, :greater_than=>0, :unless => Proc.new { |r| r.id.nil? }
         | 
| 18 | 
            +
                validates_numericality_of :section_id, :only_integer=>true, :greater_than=>0
         | 
| 19 | 
            +
                validates_presence_of :name
         | 
| 6 20 |  | 
| 7 | 
            -
             | 
| 21 | 
            +
             | 
| 22 | 
            +
                # Get structure for the flexi record
         | 
| 8 23 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 9 | 
            -
                # @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
         | 
| 10 | 
            -
                # @param [Fixnum] id the id of the Flexi Record
         | 
| 11 24 | 
             
                # @!macro options_get
         | 
| 12 | 
            -
                # @return [Array<Osm:: | 
| 13 | 
            -
                def  | 
| 14 | 
            -
                  section_id  | 
| 15 | 
            -
                  cache_key = [' | 
| 25 | 
            +
                # @return [Array<Osm::FlexiRecordColumn>] representing the columns of the flexi record
         | 
| 26 | 
            +
                def get_columns(api, options={})
         | 
| 27 | 
            +
                  require_ability_to(api, :read, :flexi, section_id, options)
         | 
| 28 | 
            +
                  cache_key = ['flexi_record_columns', self.id]
         | 
| 16 29 |  | 
| 17 | 
            -
                  if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key) | 
| 30 | 
            +
                  if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
         | 
| 18 31 | 
             
                    return Osm::Model.cache_read(api, cache_key)
         | 
| 19 32 | 
             
                  end
         | 
| 20 33 |  | 
| 21 | 
            -
                  data = api.perform_query("extras.php?action=getExtra§ionid=#{section_id}&extraid=#{id}")
         | 
| 34 | 
            +
                  data = api.perform_query("extras.php?action=getExtra§ionid=#{self.section_id}&extraid=#{self.id}")
         | 
| 22 35 |  | 
| 23 36 | 
             
                  structure = []
         | 
| 24 37 | 
             
                  data['structure'].each do |item|
         | 
| 25 38 | 
             
                    item['rows'].each do |row|
         | 
| 26 | 
            -
                      structure.push Osm::FlexiRecord:: | 
| 39 | 
            +
                      structure.push Osm::FlexiRecord::Column.new(
         | 
| 27 40 | 
             
                        :id => row['field'],
         | 
| 28 41 | 
             
                        :name => row['name'],
         | 
| 29 42 | 
             
                        :editable => row['editable'] || false,
         | 
| 43 | 
            +
                        :flexi_record => self,
         | 
| 30 44 | 
             
                      )
         | 
| 31 45 | 
             
                    end
         | 
| 32 46 | 
             
                  end
         | 
| @@ -35,15 +49,13 @@ module Osm | |
| 35 49 | 
             
                  return structure
         | 
| 36 50 | 
             
                end
         | 
| 37 51 |  | 
| 38 | 
            -
                # Add a  | 
| 52 | 
            +
                # Add a column in OSM
         | 
| 39 53 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 40 | 
            -
                # @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
         | 
| 41 | 
            -
                # @param [Fixnum] id the id of the Flexi Record
         | 
| 42 54 | 
             
                # @param [String] name The name for the created column
         | 
| 43 | 
            -
                # @return [Boolean] whether the  | 
| 44 | 
            -
                def  | 
| 55 | 
            +
                # @return [Boolean] whether the column was created in OSM
         | 
| 56 | 
            +
                def add_column(api, name)
         | 
| 57 | 
            +
                  require_ability_to(api, :write, :flexi, section_id)
         | 
| 45 58 | 
             
                  raise ArgumentError, 'name is invalid' if name.blank?
         | 
| 46 | 
            -
                  section_id = section.to_i
         | 
| 47 59 |  | 
| 48 60 | 
             
                  data = api.perform_query("extras.php?action=addColumn§ionid=#{section_id}&extraid=#{id}", {
         | 
| 49 61 | 
             
                    'columnName' => name,
         | 
| @@ -53,35 +65,7 @@ module Osm | |
| 53 65 | 
             
                    ActiveSupport::JSON.decode(data['config']).each do |field|
         | 
| 54 66 | 
             
                      if field['name'] == name
         | 
| 55 67 | 
             
                        # The cached fields for the flexi record will be out of date - remove them
         | 
| 56 | 
            -
                         Osm::Model.cache_delete(api, [' | 
| 57 | 
            -
                        return true
         | 
| 58 | 
            -
                      end
         | 
| 59 | 
            -
                    end
         | 
| 60 | 
            -
                  end
         | 
| 61 | 
            -
                  return false
         | 
| 62 | 
            -
                end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                # Update a field in OSM
         | 
| 65 | 
            -
                # @param [Osm::Api] api The api to use to make the request
         | 
| 66 | 
            -
                # @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
         | 
| 67 | 
            -
                # @param [Fixnum] id the id of the Flexi Record
         | 
| 68 | 
            -
                # @param [String] field the id of the Flexi Record Field
         | 
| 69 | 
            -
                # @param [String] name The new name for the created column
         | 
| 70 | 
            -
                # @return [Boolean] whether the field was updated in OSM
         | 
| 71 | 
            -
                def self.update_field(api, section, id, field, name)
         | 
| 72 | 
            -
                  raise ArgumentError, 'name is invalid' if name.blank?
         | 
| 73 | 
            -
                  section_id = section.to_i
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  data = api.perform_query("extras.php?action=renameColumn§ionid=#{section_id}&extraid=#{id}", {
         | 
| 76 | 
            -
                    'columnId' => field,
         | 
| 77 | 
            -
                    'columnName' => name,
         | 
| 78 | 
            -
                  })
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                  if (data.is_a?(Hash) && data.has_key?('config'))
         | 
| 81 | 
            -
                    ActiveSupport::JSON.decode(data['config']).each do |f|
         | 
| 82 | 
            -
                      if (f['id'] == field) && (f['name'] == name)
         | 
| 83 | 
            -
                        # The cached fields for the flexi record will be out of date - remove them
         | 
| 84 | 
            -
                        Osm::Model.cache_delete(api, ['flexi_record_fields', id])
         | 
| 68 | 
            +
                         Osm::Model.cache_delete(api, ['flexi_record_columns', id])
         | 
| 85 69 | 
             
                        return true
         | 
| 86 70 | 
             
                      end
         | 
| 87 71 | 
             
                    end
         | 
| @@ -89,46 +73,18 @@ module Osm | |
| 89 73 | 
             
                  return false
         | 
| 90 74 | 
             
                end
         | 
| 91 75 |  | 
| 92 | 
            -
                # Update a field in OSM
         | 
| 93 | 
            -
                # @param [Osm::Api] api The api to use to make the request
         | 
| 94 | 
            -
                # @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
         | 
| 95 | 
            -
                # @param [Fixnum] id the id of the Flexi Record
         | 
| 96 | 
            -
                # @param [String] field the id of the Flexi Record Field
         | 
| 97 | 
            -
                # @return [Boolean] whether the field was updated in OSM
         | 
| 98 | 
            -
                def self.delete_field(api, section, id, field)
         | 
| 99 | 
            -
                  section_id = section.to_i
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                  data = api.perform_query("extras.php?action=deleteColumn§ionid=#{section_id}&extraid=#{id}", {
         | 
| 102 | 
            -
                    'columnId' => field,
         | 
| 103 | 
            -
                  })
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                  if (data.is_a?(Hash) && data.has_key?('config'))
         | 
| 106 | 
            -
                    ActiveSupport::JSON.decode(data['config']).each do |f|
         | 
| 107 | 
            -
                      if f['id'] == field
         | 
| 108 | 
            -
                        # It wasn't deleted
         | 
| 109 | 
            -
                        return false
         | 
| 110 | 
            -
                      end
         | 
| 111 | 
            -
                    end
         | 
| 112 | 
            -
                  end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                  # The cached fields for the flexi record will be out of date - remove them
         | 
| 115 | 
            -
                  Osm::Model.cache_delete(api, ['flexi_record_fields', id])
         | 
| 116 | 
            -
                  return true
         | 
| 117 | 
            -
                end
         | 
| 118 | 
            -
             | 
| 119 76 | 
             
                # Get data for flexi record
         | 
| 120 77 | 
             
                # @param [Osm::Api] api The api to use to make the request
         | 
| 121 | 
            -
                # @param [Osm:: | 
| 122 | 
            -
                # @param [Fixnum] the id of the Flexi Record
         | 
| 123 | 
            -
                # @param [Osm::Term, Fixnum, nil] section the term (or its ID) to get the register for, passing nil causes the current term to be used
         | 
| 78 | 
            +
                # @param [Osm::Term, Fixnum, #to_i, nil] term The term (or its ID) to get the register for, passing nil causes the current term to be used
         | 
| 124 79 | 
             
                # @!macro options_get
         | 
| 125 80 | 
             
                # @return [Array<FlexiRecordData>]
         | 
| 126 | 
            -
                def  | 
| 127 | 
            -
                   | 
| 81 | 
            +
                def get_data(api, term=nil, options={})
         | 
| 82 | 
            +
                  require_ability_to(api, :read, :flexi, section_id, options)
         | 
| 83 | 
            +
                  section = Osm::Section.get(api, self.section_id)
         | 
| 128 84 | 
             
                  term_id = term.nil? ? Osm::Term.get_current_term_for_section(api, section).id : term.to_i
         | 
| 129 85 | 
             
                  cache_key = ['flexi_record_data', id, term_id]
         | 
| 130 86 |  | 
| 131 | 
            -
                  if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key) | 
| 87 | 
            +
                  if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
         | 
| 132 88 | 
             
                    return Osm::Model.cache_read(api, cache_key)
         | 
| 133 89 | 
             
                  end
         | 
| 134 90 |  | 
| @@ -150,7 +106,8 @@ module Osm | |
| 150 106 | 
             
                      to_return.push Osm::FlexiRecord::Data.new(
         | 
| 151 107 | 
             
                        :member_id => Osm::to_i_or_nil(item['scoutid']),
         | 
| 152 108 | 
             
                        :grouping_id => Osm::to_i_or_nil(item['patrolid'].eql?('') ? nil : item['patrolid']),
         | 
| 153 | 
            -
                        :fields => fields
         | 
| 109 | 
            +
                        :fields => fields,
         | 
| 110 | 
            +
                        :flexi_record => self,
         | 
| 154 111 | 
             
                      )
         | 
| 155 112 | 
             
                    end
         | 
| 156 113 | 
             
                  end
         | 
| @@ -159,40 +116,20 @@ module Osm | |
| 159 116 | 
             
                  return to_return
         | 
| 160 117 | 
             
                end
         | 
| 161 118 |  | 
| 162 | 
            -
                # Update a field in OSM
         | 
| 163 | 
            -
                # @param [Osm::Api] api The api to use to make the request
         | 
| 164 | 
            -
                # @param [Osm::Section, Fixnum] section the section (or its ID) to update the data for
         | 
| 165 | 
            -
                # @param [Fixnum] flexi_record_id the id of the Flexi Record
         | 
| 166 | 
            -
                # @param [Osm::Member, Fixnum] member the member (or their ID) to update
         | 
| 167 | 
            -
                # @param [String] column the id of the Flexi Record Field
         | 
| 168 | 
            -
                # @param [String] value The updated value
         | 
| 169 | 
            -
                # @return [Boolean] whether the field was updated in OSM
         | 
| 170 | 
            -
                def self.update_data(api, section, flexi_record_id, member, column, value)
         | 
| 171 | 
            -
                  raise ArgumentError, 'name is invalid' if name.blank?
         | 
| 172 | 
            -
                  section_id = section.to_i
         | 
| 173 | 
            -
                  member_id = member.to_i
         | 
| 174 | 
            -
                  term_id = Osm::Term.get_current_term_for_section(api, section).id
         | 
| 175 | 
            -
             | 
| 176 | 
            -
                  data = api.perform_query("extras.php?action=updateScout", {
         | 
| 177 | 
            -
                    'termid' => term_id,
         | 
| 178 | 
            -
                    'scoutid' => member_id,
         | 
| 179 | 
            -
                    'column' => column,
         | 
| 180 | 
            -
                    'value' => value,
         | 
| 181 | 
            -
                    'sectionid' => section_id,
         | 
| 182 | 
            -
                    'extraid' => flexi_record_id,
         | 
| 183 | 
            -
                  })
         | 
| 184 119 |  | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 120 | 
            +
                def <=>(another)
         | 
| 121 | 
            +
                  begin
         | 
| 122 | 
            +
                    return self.name <=> another.name
         | 
| 123 | 
            +
                  rescue NoMethodError
         | 
| 124 | 
            +
                    return 1
         | 
| 189 125 | 
             
                  end
         | 
| 190 | 
            -
                  return false
         | 
| 191 126 | 
             
                end
         | 
| 192 127 |  | 
| 193 128 |  | 
| 194 129 |  | 
| 195 | 
            -
                class  | 
| 130 | 
            +
                class Column < Osm::Model
         | 
| 131 | 
            +
                  # @!attribute [rw] flexi_record
         | 
| 132 | 
            +
                  #   @return [Boolean] The FlexiRecord this column belongs to
         | 
| 196 133 | 
             
                  # @!attribute [rw] id
         | 
| 197 134 | 
             
                  #   @return [String] OSM identifier for the field. Special ones are 'dob', 'total', 'completed', 'age', 'firstname' and 'lastname', user ones are of the format 'f\_NUMBER'
         | 
| 198 135 | 
             
                  # @!attribute [rw] name
         | 
| @@ -200,24 +137,83 @@ module Osm | |
| 200 137 | 
             
                  # @!attribute [rw] editable
         | 
| 201 138 | 
             
                  #   @return [Boolean] Wether the field can be edited
         | 
| 202 139 |  | 
| 140 | 
            +
                  attribute :flexi_record, :type => Object
         | 
| 203 141 | 
             
                  attribute :id, :type => String
         | 
| 204 142 | 
             
                  attribute :name, :type => String
         | 
| 205 143 | 
             
                  attribute :editable, :type => Boolean, :default => false
         | 
| 206 144 |  | 
| 207 | 
            -
                  attr_accessible :id, :name, :editable
         | 
| 145 | 
            +
                  attr_accessible :flexi_record, :id, :name, :editable
         | 
| 208 146 |  | 
| 147 | 
            +
                  validates_presence_of :flexi_record
         | 
| 209 148 | 
             
                  validates_presence_of :id
         | 
| 210 149 | 
             
                  validates_presence_of :name
         | 
| 211 150 | 
             
                  validates_inclusion_of :editable, :in => [true, false]
         | 
| 212 151 |  | 
| 213 152 | 
             
                  # @!method initialize
         | 
| 214 | 
            -
                  #   Initialize a new  | 
| 215 | 
            -
                  #   @param [Hash] attributes  | 
| 153 | 
            +
                  #   Initialize a new FlexiRecord::Column
         | 
| 154 | 
            +
                  #   @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
         | 
| 155 | 
            +
             | 
| 156 | 
            +
             | 
| 157 | 
            +
                  # Update a column in OSM
         | 
| 158 | 
            +
                  # @param [Osm::Api] api The api to use to make the request
         | 
| 159 | 
            +
                  # @return [Boolean] whether the column was updated in OSM
         | 
| 160 | 
            +
                  # @raise [Osm::ObjectIsInvalid] If the Column is invalid
         | 
| 161 | 
            +
                  # @raise [Osm::Forbidden] If the COlumn is not editable
         | 
| 162 | 
            +
                  def update(api)
         | 
| 163 | 
            +
                    raise Osm::ObjectIsInvalid, 'column is invalid' unless valid?
         | 
| 164 | 
            +
                    require_ability_to(api, :write, :flexi, flexi_record.section_id)
         | 
| 165 | 
            +
                    raise Osm::Forbidden, 'this column is not editable' unless self.editable
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                    data = api.perform_query("extras.php?action=renameColumn§ionid=#{flexi_record.section_id}&extraid=#{flexi_record.id}", {
         | 
| 168 | 
            +
                      'columnId' => self.id,
         | 
| 169 | 
            +
                      'columnName' => self.name,
         | 
| 170 | 
            +
                    })
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                    if (data.is_a?(Hash) && data.has_key?('config'))
         | 
| 173 | 
            +
                      ActiveSupport::JSON.decode(data['config']).each do |f|
         | 
| 174 | 
            +
                        if (f['id'] == self.id) && (f['name'] == self.name)
         | 
| 175 | 
            +
                          reset_changed_attributes
         | 
| 176 | 
            +
                          # The cached columns for the flexi record will be out of date - remove them
         | 
| 177 | 
            +
                          cache_delete(api, ['flexi_record_columns', flexi_record.id])
         | 
| 178 | 
            +
                          return true
         | 
| 179 | 
            +
                        end
         | 
| 180 | 
            +
                      end
         | 
| 181 | 
            +
                    end
         | 
| 182 | 
            +
                    return false
         | 
| 183 | 
            +
                  end
         | 
| 216 184 |  | 
| 217 | 
            -
             | 
| 185 | 
            +
                  # Delete a column in OSM
         | 
| 186 | 
            +
                  # @param [Osm::Api] api The api to use to make the request
         | 
| 187 | 
            +
                  # @return [Boolean] whether the column was deleted from OSM
         | 
| 188 | 
            +
                  # @raise [Osm::Forbidden] If this Column is not editable
         | 
| 189 | 
            +
                  def delete(api)
         | 
| 190 | 
            +
                    require_ability_to(api, :write, :flexi, flexi_record.section_id)
         | 
| 191 | 
            +
                    raise Osm::Forbidden, 'this column is not editable' unless self.editable
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                    data = api.perform_query("extras.php?action=deleteColumn§ionid=#{flexi_record.section_id}&extraid=#{flexi_record.id}", {
         | 
| 194 | 
            +
                      'columnId' => self.id,
         | 
| 195 | 
            +
                    })
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                    if (data.is_a?(Hash) && data.has_key?('config'))
         | 
| 198 | 
            +
                      ActiveSupport::JSON.decode(data['config']).each do |f|
         | 
| 199 | 
            +
                        if f['id'] == self.id
         | 
| 200 | 
            +
                          # It wasn't deleted
         | 
| 201 | 
            +
                          return false
         | 
| 202 | 
            +
                        end
         | 
| 203 | 
            +
                      end
         | 
| 204 | 
            +
                    end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                    # The cached columns for the flexi record will be out of date - remove them
         | 
| 207 | 
            +
                    cache_delete(api, ['flexi_record_columns', flexi_record.id])
         | 
| 208 | 
            +
                    return true
         | 
| 209 | 
            +
                  end
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                end # Class FlexiRecord::Column
         | 
| 218 212 |  | 
| 219 213 |  | 
| 220 214 | 
             
                class Data < Osm::Model
         | 
| 215 | 
            +
                  # @!attribute [rw] flexi_record
         | 
| 216 | 
            +
                  #   @return [Boolean] The FlexiRecord this column belongs to
         | 
| 221 217 | 
             
                  # @!attribute [rw] member_id
         | 
| 222 218 | 
             
                  #   @return [Fixnum] OSM id for the member
         | 
| 223 219 | 
             
                  # @!attribute [rw] grouping__id
         | 
| @@ -225,20 +221,65 @@ module Osm | |
| 225 221 | 
             
                  # @!attribute [rw] fields
         | 
| 226 222 | 
             
                  #   @return [Hash] Keys are the field's id, values are the field values
         | 
| 227 223 |  | 
| 224 | 
            +
                  attribute :flexi_record, :type => Object
         | 
| 228 225 | 
             
                  attribute :member_id, :type => Integer
         | 
| 229 226 | 
             
                  attribute :grouping_id, :type => Integer
         | 
| 230 227 | 
             
                  attribute :fields, :default => {}
         | 
| 231 228 |  | 
| 232 | 
            -
                  attr_accessible :member_id, :grouping_id, :fields
         | 
| 229 | 
            +
                  attr_accessible :flexi_record, :member_id, :grouping_id, :fields
         | 
| 233 230 |  | 
| 231 | 
            +
                  validates_presence_of :flexi_record
         | 
| 234 232 | 
             
                  validates_numericality_of :member_id, :only_integer=>true, :greater_than=>0
         | 
| 235 233 | 
             
                  validates_numericality_of :grouping_id, :only_integer=>true, :greater_than_or_equal_to=>-2
         | 
| 236 234 | 
             
                  validates :fields, :hash => {:key_type => String}
         | 
| 237 235 |  | 
| 238 236 | 
             
                  # @!method initialize
         | 
| 239 | 
            -
                  #   Initialize a new  | 
| 240 | 
            -
                  #   @param [Hash] attributes  | 
| 241 | 
            -
             | 
| 237 | 
            +
                  #   Initialize a new FlexiRecord::Data
         | 
| 238 | 
            +
                  #   @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
         | 
| 239 | 
            +
             | 
| 240 | 
            +
             | 
| 241 | 
            +
                  # Update data in OSM
         | 
| 242 | 
            +
                  # @param [Osm::Api] api The api to use to make the request
         | 
| 243 | 
            +
                  # @return [Boolean] whether the data was updated in OSM
         | 
| 244 | 
            +
                  # @raise [Osm::ObjectIsInvalid] If the Data is invalid
         | 
| 245 | 
            +
                  def update(api)
         | 
| 246 | 
            +
                    raise Osm::ObjectIsInvalid, 'data is invalid' unless valid?
         | 
| 247 | 
            +
                    require_ability_to(api, :write, :flexi, flexi_record.section_id)
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                    term_id = Osm::Term.get_current_term_for_section(api, flexi_record.section_id).id
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                    updated = true
         | 
| 252 | 
            +
                    flexi_record.get_columns(api).each do |column|
         | 
| 253 | 
            +
                      if column.editable
         | 
| 254 | 
            +
                        data = api.perform_query("extras.php?action=updateScout", {
         | 
| 255 | 
            +
                          'termid' => term_id,
         | 
| 256 | 
            +
                          'scoutid' => self.member_id,
         | 
| 257 | 
            +
                          'column' => column.id,
         | 
| 258 | 
            +
                          'value' => fields[column.id],
         | 
| 259 | 
            +
                          'sectionid' => flexi_record.section_id,
         | 
| 260 | 
            +
                          'extraid' => flexi_record.id,
         | 
| 261 | 
            +
                        })
         | 
| 262 | 
            +
                        if (data.is_a?(Hash) && data['items'].is_a?(Array))
         | 
| 263 | 
            +
                          data['items'].each do |item|
         | 
| 264 | 
            +
                            if item['scoutid'] == member_id.to_s  # Find this member from the list of all members
         | 
| 265 | 
            +
                              updated = false unless item[column.id] == self.fields[column.id]
         | 
| 266 | 
            +
                            end
         | 
| 267 | 
            +
                          end
         | 
| 268 | 
            +
                        else
         | 
| 269 | 
            +
                          updated = false
         | 
| 270 | 
            +
                        end
         | 
| 271 | 
            +
                      end
         | 
| 272 | 
            +
                    end
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                    if updated
         | 
| 275 | 
            +
                      reset_changed_attributes
         | 
| 276 | 
            +
                      # The cached datas for the flexi record will be out of date - remove them
         | 
| 277 | 
            +
                      cache_delete(api, ['flexi_record_data', flexi_record.id])
         | 
| 278 | 
            +
                    end
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                    return updated
         | 
| 281 | 
            +
                  end
         | 
| 282 | 
            +
             | 
| 242 283 | 
             
                end # Class FlexiRecord::Data
         | 
| 243 284 |  | 
| 244 285 | 
             
              end # Class FlexiRecord
         |