app/models/application_letter.rb
# == Schema Information## Table name: application_letters## id :integer not null, primary key# allergies :string# annotation :text# custom_application_fields :text# emergency_number :string# motivation :string# organisation :string# status :integer default("pending"), not null# status_notification_sent :boolean default(FALSE), not null# vegan :boolean# vegetarian :boolean# created_at :datetime not null# updated_at :datetime not null# event_id :integer not null# user_id :integer not null## Indexes## index_application_letters_on_event_id (event_id)# index_application_letters_on_user_id (user_id)# class ApplicationLetter < ActiveRecord::Base belongs_to :user belongs_to :event has_many :application_notes, dependent: :destroy serialize :custom_application_fields, Array validates_presence_of :user, :event, :motivation, :emergency_number, :organisation # Use 0 as default for hidden event applications validates :vegetarian, :vegan, :allergic, inclusion: { in: [true, false] } validates :vegetarian, :vegan, :allergic, exclusion: { in: [nil] } validate :deadline_cannot_be_in_the_past, if: proc { |letter| !(letter.status_changed? || letter.status_notification_sent_changed?) } validate :status_notification_sent_cannot_be_changed, if: proc { |letter| letter.status_notification_sent_changed? } validate :status_cannot_be_changed, if: proc { |letter| letter.status_changed? } enum status: { accepted: 1, rejected: 0, pending: 2, alternative: 3, canceled: 4 } validates :status, inclusion: { in: statuses.keys } # Returns an array of selectable statuses # # @param none # @return [Array <String>] array of selectable statuses def self.selectable_statuses`%w`-literals should be delimited by `[` and `]`. %w(accepted rejected pending alternative) end # Checks if the deadline is over # additionally only return if event and event.application_deadline is present # # @param none # @return [Boolean] true if deadline is over def after_deadline? event.after_deadline? if event.present? end # Checks if it is allowed to change the status of the application # # @param none # @return [Boolean] true if status changes are allowedMethod `status_change_allowed?` has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring. def status_change_allowed?Consider simplifying this complex logical expression. if event.phase == :execution (status_was == 'accepted' && status == 'canceled') || (status_was == 'alternative' && status == 'accepted') || (status_was == 'rejected' && status == 'accepted' && !event.has_alternative_application_letters?) elsif event.phase == :selection && event.participant_selection_locked false else true end end # Checks if it is allowed to set the status_notification_sent flag # # @param none # @return [Boolean] true if it can be changed def status_notification_sent_change_allowed? event.phase == :selection || event.phase == :execution end # Validator for after_deadline? # Adds error def deadline_cannot_be_in_the_pastFavor modifier `if` usage when having a single-line body. Another good alternative is the usage of control flow `&&`/`||`. if after_deadline? errors.add(:event, I18n.t('application_letters.form.warning')) end end # Since EatingHabits are persited in booleans we need to generate a # EatingHabitStateCode to allow sorting # US 28_4.5 def get_eating_habit_state eating_habit_state = 0 eating_habit_state += 4 if vegetarian eating_habit_state += 5 if vegan eating_habit_state += 99 if allergic eating_habit_state end # Chooses right status based on status and event deadline # # @param none # @return [String] to display on the website def status_type case ApplicationLetter.statuses[status] when ApplicationLetter.statuses[:accepted] I18n.t('application_status.accepted') when ApplicationLetter.statuses[:rejected] I18n.t('application_status.rejected') when ApplicationLetter.statuses[:pending] if after_deadline? I18n.t('application_status.pending_after_deadline') else I18n.t('application_status.pending_before_deadline') end when ApplicationLetter.statuses[:canceled] I18n.t('application_status.canceled') else I18n.t('application_status.alternative') end end # Validator for status_change_allowed? # Adds error def status_cannot_be_changedFavor modifier `unless` usage when having a single-line body. Another good alternative is the usage of control flow `&&`/`||`. unless status_change_allowed? errors.add(:event, I18n.t('application_letters.validation.status_cannot_be_changed')) end end # Validator for status_change_allowed? # Adds error def status_notification_sent_cannot_be_changedFavor modifier `unless` usage when having a single-line body. Another good alternative is the usage of control flow `&&`/`||`. unless status_notification_sent_change_allowed? errors.add(:event, I18n.t('application_letters.validation.status_notification_sent_cannot_be_changed')) end end # Returns the age of the user based on the date the event starts # # @param none # @return [Int] for age as number of years def applicant_age_when_event_starts user.profile.age_at_time(event.start_date) end # Returns an array of eating habits (including allergies, vegan and vegetarian) # # @param none # @return [Array <String>] array of eating habits, empty if none def eating_habits habits = [] habits.push(ApplicationLetter.human_attribute_name(:vegetarian)) if vegetarian habits.push(ApplicationLetter.human_attribute_name(:vegan)) if vegan habits.push(ApplicationLetter.human_attribute_name(:allergies)) if allergic habits end def allergic !allergies.empty? endend