| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 | 
							- # A person represents a human being. A Person may be a Member in one or more
 
- # Groups, and be a Participant in any number of events of those Groups.
 
- # A Person may access the system by creating a User, and may have at most one
 
- # User.
 
- class Person < ApplicationRecord
 
-   include Rails.application.routes.url_helpers
 
-   # @!attribute first_name
 
-   #   @return [String]
 
-   #     the person's first name. ('Vincent' in 'Vincent van Gogh'.)
 
-   #
 
-   # @!attribute infix
 
-   #   @return [String]
 
-   #     the part of a person's surname that is not taken into account when
 
-   #     sorting by surname. ('van' in 'Vincent van Gogh'.)
 
-   #
 
-   # @!attribute last_name
 
-   #   @return [String]
 
-   #     the person's surname. ('Gogh' in 'Vincent van Gogh'.)
 
-   #
 
-   # @!attribute email
 
-   #   @return [String]
 
-   #     the person's email address.
 
-   #
 
-   # @!attribute calendar_token
 
-   #   @return [String]
 
-   #     the calendar token that can be used to open this Person's events as an
 
-   #     ICAL file.
 
-   #
 
-   # @!attribute is_admin
 
-   #   @return [Boolean]
 
-   #     whether or not the person has administrative rights.
 
-   has_one :user, dependent: :destroy
 
-   has_many :members,
 
-            dependent: :destroy
 
-   has_many :participants,
 
-            dependent: :destroy
 
-   has_many :groups, through: :members
 
-   has_many :activities, through: :participants
 
-   has_secure_token :calendar_token
 
-   validates :email, uniqueness: true
 
-   validates :first_name, presence: true
 
-   validates :last_name, presence: true
 
-   before_validation :not_admin_if_nil
 
-   before_save :update_user_email, if: :email_changed?
 
-   # The person's full name.
 
-   def full_name
 
-     if infix&.present?
 
-       [first_name, infix, last_name].join(' ')
 
-     else
 
-       [first_name, last_name].join(' ')
 
-     end
 
-   end
 
-   # The person's reversed name, to sort by surname.
 
-   def reversed_name
 
-     if infix
 
-       [last_name, infix, first_name].join(', ')
 
-     else
 
-       [last_name, first_name].join(', ')
 
-     end
 
-   end
 
-   # All activities where this person is an organizer.
 
-   def organized_activities
 
-     participants.includes(:activity).where(is_organizer: true)
 
-   end
 
-   # Create multiple Persons from data found in a csv file, return those.
 
-   def self.from_csv(content)
 
-     reader = CSV.parse(content, headers: true, skip_blanks: true)
 
-     result = []
 
-     reader.each do |row|
 
-       p = Person.find_by(email: row['email'])
 
-       unless p
 
-         p = Person.new
 
-         p.first_name  = row['first_name']
 
-         p.infix       = row['infix']
 
-         p.last_name   = row['last_name']
 
-         p.email       = row['email']
 
-         p.save!
 
-       end
 
-       result << p
 
-     end
 
-     result
 
-   end
 
-   # @return [String]
 
-   #   the URL to access this person's calendar.
 
-   def calendar_url
 
-     person_calendar_url calendar_token
 
-   end
 
-   # @return [Icalendar::Calendar]
 
-   #   this Person's upcoming activities feed.
 
-   def calendar_feed(skip_absent = false)
 
-     cal = Icalendar::Calendar.new
 
-     cal.x_wr_calname = 'Aardbei'
 
-     tzid = 1.second.since.time_zone.tzinfo.name
 
-     selection =
 
-       participants
 
-       .joins(:activity)
 
-       .where('"end" > ?', 3.months.ago)
 
-     if skip_absent
 
-       selection = selection
 
-                   .where.not(attending: false)
 
-     end
 
-     selection.each do |p|
 
-       a = p.activity
 
-       description_items = []
 
-       # The description consists of the following parts:
 
-       #  - The Participant's response and notes (if set),
 
-       #  - The Activity's description (if not empty),
 
-       #  - The names of the organizers,
 
-       #  - Subgroup information, if applicable,
 
-       #  - The URL.
 
-       # Response
 
-       yourresponse = "#{I18n.t 'activities.participant.yourresponse'}: #{p.human_attending}"
 
-       yourresponse << " (#{p.notes})" if p.notes.present?
 
-       description_items << yourresponse
 
-       # Description
 
-       description_items << a.description if a.description.present?
 
-       # Organizers
 
-       orgi = a.organizer_names
 
-       orgi_names = orgi.join ', '
 
-       orgi_line = case orgi.count
 
-                   when 0 then I18n.t 'activities.organizers.no_organizers'
 
-                   when 1 then "#{I18n.t 'activities.organizers.one'}: #{orgi_names}"
 
-                   else "#{I18n.t 'activities.organizers.other'}: #{orgi_names}"
 
-                   end
 
-       description_items << orgi_line
 
-       # Subgroups
 
-       if a.subgroups.any?
 
-         description_items << "#{I18n.t 'activities.participant.yoursubgroup'}: #{p.subgroup}" if p.subgroup
 
-         subgroup_names = a.subgroups.map(&:name).join ', '
 
-         description_items << "#{I18n.t 'activerecord.models.subgroup.other'}: #{subgroup_names}"
 
-       end
 
-       # URL
 
-       a_url = group_activity_url a.group, a
 
-       description_items << a_url
 
-       cal.event do |e|
 
-         e.uid = a_url
 
-         e.dtstart = Icalendar::Values::DateTime.new a.start, tzid: tzid
 
-         e.dtend =   Icalendar::Values::DateTime.new a.end,   tzid: tzid
 
-         e.status = p.ical_attending
 
-         e.summary = a.name
 
-         e.location = a.location
 
-         e.description = description_items.join "\n"
 
-         e.url = a_url
 
-       end
 
-     end
 
-     cal.publish
 
-     cal
 
-   end
 
-   private
 
-   # Explicitly force nil to false in the admin field.
 
-   def not_admin_if_nil
 
-     self.is_admin ||= false
 
-   end
 
-   # Ensure the person's user email is updated at the same time as the person's
 
-   # email.
 
-   def update_user_email
 
-     user&.update!(email: email)
 
-   end
 
- end
 
 
  |