Skip to content

Rooming Feature

Brent edited this page Apr 16, 2019 · 20 revisions

I wanted to write down some ideas I have on how to implement the rooming feature of Workshops, and this seems like as good a place as any.

Core functionality

As the card outlines, the core functionality of the rooming feature should be:

  • information about what rooms are available for staff to assign to workshop participants should be stored in the database, to make it easy for Workshops to be used to organize events at any venue.

  • the interface for assigning rooms should be intuitive and resistant to human error

  • it should support overlapping event dates

  • it should have a flexible structure for the unlimited possibilities of accommodation types

Implementation ideas

Data Structure

The data structure for storing the types of rooms available for a location could be a multi-dimensional array, stored in the database (the Settings feature can already provide this). To allow for various locations, each with their own set of rooms, it could have this structure:

{
   'Space 1' => [ 'room 1', 'room 2', 'room 3', ... ], 
   'Space 2' => [ 'room 1', 'room 2', 'room 3'...]
}

To take the example of one of the BIRS locations, the CMO, guests stay one of two in hotels. The staff must assign rooms to incoming event participants. So the Room Setting for CMO might be something like:

{
   'Hacienda Los Laureles' => [ 'Suite 001', 'Suite 002', 'Suite 003'... ],
   'Hotel Angel Inn' => [ 'Room 102', 'Room 203', 'Room 304'... ]
}

One could choose to divide a space up, for example have a space for each floor of the same building:

{
   'Corbett Hall Floor 1' => [ 'CH 5011', 'CH 5012', 'CH 5012'... ],
   'Corbett Hall Floor 2' => [ 'CH 5021', 'CH 5022', 'CH 5023'... ],
}

Visual booking

For each space, a simple interactive graphic representation of the "space", such as a rectangle, could be presented to the user (who is booking rooms for event members). Within the rectangle would be clickable squares representing each room. The user could click on a room to assign it to an event participant.

This is why one might want to represent a building as one space per floor -- because a limited number of squares will fit on the graphic representation of rooms inside the rectangle (space).

In the Membership list, a navigation section could be called "Rooming" or "Room Booking". This would list the confirmed members, with a column for "Room", and a clickable link in that column: "(Not Set)" or e.g. Room 211. Clicking the link would bring up the visual representation, where the user could click through to the space they want, and then click on the room within that space, to assign.

I had in mind staff users would be doing this, but it might even be desirable to have participants choose their own rooms...

Automated room assignment

Another helpful feature would be a way to automatically assign rooms to all participants, based on a set of rules that is configurable to the user. The staff member could start off by clicking the "Assign Rooms Automatically" button, which would assign an available room to every confirmed participant.

This could be a random assignment, if no rules are set. But I envision a part of the Room settings for storing automatic assignment rules. For example, perhaps there is some reason to assign males to one space, and females to another. Or senior researchers together, and junior researchers together. In any case, a way to assign arbitrary criteria for random room assignment within user-set constraints.

'Automated Assignment' => [
  {
    'space' => 'space name',
    'condition' => [
      [ 'attribute name', 'operator', 'comparison string' ],
      [ 'attribute name', 'operator', 'comparison string' ]
    ],
  },...
}

So for example, to have all Professors from France automatically assigned to an available room in the space named "Grand-Hôtel", and all participants with the role "Observer" assigned to a room in "Hotel ibis", and anyone with the word "vegetarian" in the membership.special_info field assigned to the space named "Avalon", you would have a setting such as:

'Automated Assignment' => [
  {
    'space' => 'Grand-Hôtel',
    'condition' => [
      [ 'person.country', '==', 'France' ],
      [ 'person.title', '=~', '/Professor/' ]
    ],
  },
  {
    'space' => 'Hotel ibis',
    'condition' => [
      [ 'role', '==', 'Observer' ]
    ]
  },
    'space' => 'Avalon',
    'condition' => [
      [ 'special_info', '=~', '/[Vv]egetarian/' ]
    ]
  }
]

Then we can iterate over the 'Automated Assignment' array, and for each item, assign event participants based on the space and conditions given in the settings. If there are remaining unassigned participants, assign them a random space & room.

Implementation might be something like this:

assignments = GetSetting.automated_assignments(@event.location)
assignments.each do |a|
  # check each member for whether they should be booked in a['space']
  @confirmed_members.each do |member|
    book_here = false
    a['condition'].each do |c|
      attribute = nil
      if c[0] =~ /\Aperson/
       attribute = member.person.send(c[0].split('.').last)
      else
       attribute = member.send(c[0])
      end
      book_here = attribute.public_send(c[1], c[2])
      break unless book_here
    end
    assign_room(a['space'], @confirmed_members.delete(member)) if book_here      
  end
end

If there are unassigned participants after iterating over the settings, they should be assigned rooms based on a set order of preference, i.e. in case certain spaces should be filled up before others.

Clone this wiki locally