hpi-schuelerklub/workshop-portal

View on GitHub
app/models/application_letter.rb

Summary

Maintainability
A
1 hr
Test Coverage
# == 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 allowed
Method `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_past
Favor 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_changed
Favor 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_changed
Favor 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?
end
end