Sprankelprachtig aan/afmeldsysteem

activity.rb 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. # An Activity represents a single continuous event that the members of a group may attend.
  2. # An Activity belongs to a group, and has many participants.
  3. class Activity < ApplicationRecord
  4. # @!attribute public_name
  5. # @return [String]
  6. # the name that users will see if there is no {#secret_name}, or if
  7. # {#show_hidden} is `false`.
  8. #
  9. # @!attribute secret_name
  10. # @return [String]
  11. # a name that is (be default) only visible to organizers and group
  12. # leaders. Can be shown or hidden to normal participants using
  13. # {#show_hidden}.
  14. #
  15. # @!attribute description
  16. # @return [String]
  17. # a short text describing the activity. This text is always visible to
  18. # all users.
  19. #
  20. # @!attribute location
  21. # @return [String]
  22. # a short text describing where the activity will take place. Always
  23. # visible to all participants.
  24. #
  25. # @!attribute show_hidden
  26. # @return [Boolean]
  27. # Whether or not the 'secret' attributes can be viewed by the people who
  28. # aren't organizers or group leaders. Currently, only {#secret_name} is
  29. # influenced by this. More attributes may be added in the future, and
  30. # will be controlled by this toggle as well.
  31. #
  32. # @!attribute start
  33. # @return [TimeWithZone]
  34. # when the activity starts.
  35. #
  36. # @!attribute end
  37. # @return [TimeWithZone]
  38. # when the activity ends.
  39. #
  40. # @!attribute deadline
  41. # @return [TimeWithZone]
  42. # when the normal participants (everyone who isn't an organizer or group
  43. # leader) may not change their own attendance anymore. Disabled if set to
  44. # nil.
  45. belongs_to :group
  46. has_many :participants,
  47. dependent: :destroy
  48. has_many :people, through: :participants
  49. validates :public_name, presence: true
  50. validates :start, presence: true
  51. validate :deadline_before_start, unless: "self.deadline.blank?"
  52. validate :end_after_start, unless: "self.end.blank?"
  53. after_create :create_missing_participants!
  54. # Get all people (not participants) that are organizers. Does not include
  55. # group leaders, although they may modify the activity as well.
  56. def organizers
  57. self.participants.includes(:person).where(is_organizer: true)
  58. end
  59. # Determine whether the passed Person participates in the activity.
  60. def is_participant?(person)
  61. Participant.exists?(
  62. activity_id: self.id,
  63. person_id: person.id
  64. )
  65. end
  66. # Determine whether the passed Person is an organizer for the activity.
  67. def is_organizer?(person)
  68. Participant.exists?(
  69. person_id: person.id,
  70. activity_id: self.id,
  71. is_organizer: true
  72. )
  73. end
  74. # Query the database to determine the amount of participants that are present/absent/unknown
  75. def state_counts
  76. self.participants.group(:attending).count
  77. end
  78. # Determine whether the passed Person may change this activity.
  79. def may_change?(person)
  80. person.is_admin ||
  81. self.is_organizer?(person) ||
  82. self.group.is_leader?(person)
  83. end
  84. # Create Participants for all People that
  85. # 1. are members of the group
  86. # 2. do not have Participants (and thus, no way to confirm) yet
  87. def create_missing_participants!
  88. people = self.group.people
  89. if not self.participants.empty?
  90. people = people.where('people.id NOT IN (?)', self.people.ids)
  91. end
  92. people.each do |p|
  93. Participant.create(
  94. activity: self,
  95. person: p,
  96. )
  97. end
  98. end
  99. private
  100. # Assert that the deadline for participants to change the deadline, if any,
  101. # is set before the event starts.
  102. def deadline_before_start
  103. if self.deadline > self.start
  104. errors.add(:deadline, 'must be before start')
  105. end
  106. end
  107. # Assert that the activity's end, if any, occurs after the event's start.
  108. def end_after_start
  109. if self.end < self.start
  110. errors.add(:end, 'must be after start')
  111. end
  112. end
  113. end