canvas-lms/app/models/enrollment_term.rb

138 lines
4.4 KiB
Ruby

#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class EnrollmentTerm < ActiveRecord::Base
DEFAULT_TERM_NAME = "Default Term"
include Workflow
attr_accessible :name, :start_at, :end_at, :ignore_term_date_restrictions
belongs_to :root_account, :class_name => 'Account'
has_many :enrollment_dates_overrides
has_many :courses
has_many :enrollments, :through => :courses
has_many :course_sections
before_validation :verify_unique_sis_source_id
before_save :update_courses_later_if_necessary
include StickySisFields
are_sis_sticky :name, :start_at, :end_at
def update_courses_later_if_necessary
self.update_courses_later if !self.new_record? && (self.start_at_changed? || self.end_at_changed?)
end
# specifically for use in specs
def reset_touched_courses_flag
@touched_courses = false
end
def touch_all_courses
return if new_record?
Course.update_all({:updated_at => Time.now.utc}, "enrollment_term_id=#{self.id}")
end
def update_courses_later
self.send_later_if_production(:touch_all_courses) unless @touched_courses
@touched_courses = true
end
def self.i18n_default_term_name
t '#account.default_term_name', "Default Term"
end
def default_term?
read_attribute(:name) == EnrollmentTerm::DEFAULT_TERM_NAME
end
def name
if default_term?
EnrollmentTerm.i18n_default_term_name
else
read_attribute(:name)
end
end
def name=(new_name)
if new_name == EnrollmentTerm.i18n_default_term_name
write_attribute(:name, DEFAULT_TERM_NAME)
else
write_attribute(:name, new_name)
end
end
def set_overrides(context, params)
return unless params && context
params.map do |type, values|
type = type.classify
enrollment_type = Enrollment.typed_enrollment(type).to_s
override = self.enrollment_dates_overrides.find_by_enrollment_type(enrollment_type)
override ||= self.enrollment_dates_overrides.build(:enrollment_type => enrollment_type)
# preload the reverse association - VERY IMPORTANT so that @touched_enrollments is shared
override.enrollment_term = self
override.start_at = values[:start_at]
override.end_at = values[:end_at]
override.context = context
override.save
override
end
end
def verify_unique_sis_source_id
return true unless self.sis_source_id
existing_term = self.root_account.enrollment_terms.find_by_sis_source_id(self.sis_source_id)
return true if !existing_term || existing_term.id == self.id
self.errors.add(:sis_source_id, t('errors.not_unique', "SIS ID \"%{sis_source_id}\" is already in use", :sis_source_id => self.sis_source_id))
false
end
def users_count
Enrollment.active.count(
:select => "enrollments.user_id",
:distinct => true,
:joins => :course,
:conditions => ['enrollments.course_id = courses.id AND courses.enrollment_term_id = ? AND enrollments.root_account_id = ?', id, self.root_account_id]
)
end
workflow do
state :active
state :deleted
end
def enrollment_dates_for(enrollment)
return [nil, nil] if ignore_term_date_restrictions
# detect will cause the whole collection to load; that's fine, it's a small collection, and
# we'll probably call enrollment_dates_for multiple times in a single request, so we want
# it cached, rather than using .scoped which would force a re-query every time
override = enrollment_dates_overrides.detect { |override| override.enrollment_type == enrollment.type.to_s}
[ override.try(:start_at) || start_at, override.try(:end_at) || end_at ]
end
alias_method :destroy!, :destroy
def destroy
self.workflow_state = 'deleted'
save!
end
named_scope :active, lambda {
{ :conditions => ['enrollment_terms.workflow_state != ?', 'deleted'] }
}
end