Class: CourseEnrollment

Inherits:
ApplicationRecord show all
Includes:
Models::Auditable, Models::LiquidMethods
Defined in:
app/models/course_enrollment.rb

Overview

== Schema Information

Table name: course_enrollments
Database name: primary

id :bigint not null, primary key
completion_date :datetime
enrollment_date :datetime
passed_email_reminder_sent :boolean default(FALSE)
passed_email_reminder_sent_at :datetime
passed_email_sent :boolean default(FALSE)
passed_email_sent_at :datetime
reminder_1 :datetime
reminder_2 :datetime
reminder_3 :datetime
reminder_4 :datetime
state :string not null
created_at :datetime not null
updated_at :datetime not null
course_id :integer not null
party_id :integer not null

Indexes

index_course_enrollments_on_course_id (course_id)

Foreign Keys

fk_rails_... (course_id => courses.id)

Tracks a Party's enrollment in a training Course, including state
(new/active/completed/cancelled), progress across customer topics, exam
results, certification, and the email/reminder milestones around them.

Constant Summary

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Belongs to collapse

Methods included from Models::Auditable

#creator, #updater

Has many collapse

Has one collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Class Method Details

.activeActiveRecord::Relation<CourseEnrollment>

A relation of CourseEnrollments that are active. Active Record Scope

Returns:

See Also:



60
# File 'app/models/course_enrollment.rb', line 60

scope :active, -> { where(state: 'active') }

.for_courseActiveRecord::Relation<CourseEnrollment>

A relation of CourseEnrollments that are for course. Active Record Scope

Returns:

See Also:



61
# File 'app/models/course_enrollment.rb', line 61

scope :for_course, ->(c) { where(course_id: c.id) }

.ready_to_certificateActiveRecord::Relation<CourseEnrollment>

A relation of CourseEnrollments that are ready to certificate. Active Record Scope

Returns:

See Also:



62
# File 'app/models/course_enrollment.rb', line 62

scope :ready_to_certificate, -> { left_outer_joins(:certification).where(state: :completed) }

Instance Method Details

Builds the public certificate request form URL.

Returns:

  • (String)

    certificate form URL



170
171
172
# File 'app/models/course_enrollment.rb', line 170

def certificate_form_link
  "#{WEB_URL}/my_account/course_enrollments/#{id}/certifications/new"
end

#certificate_not_requested?Boolean?

Whether no certification has been requested yet for this enrollment.

Returns:

  • (Boolean, nil)

    true when no certification exists, nil otherwise



177
178
179
# File 'app/models/course_enrollment.rb', line 177

def certificate_not_requested?
  true if certification.blank?
end

#certificationCertification?

Returns the requested certification.

Returns:



56
# File 'app/models/course_enrollment.rb', line 56

has_one :certification, dependent: :destroy

#completed?Boolean

Whether the enrollment has reached the completed state.

Returns:

  • (Boolean)


106
107
108
# File 'app/models/course_enrollment.rb', line 106

def completed?
  state == 'completed'
end

#content_completed?Boolean

Whether all assigned course content has been completed.

Returns:



125
126
127
# File 'app/models/course_enrollment.rb', line 125

def content_completed?
  progress == 100
end

#courseCourse?

Returns the enrolled course.

Returns:

  • (Course, nil)

    the enrolled course



46
# File 'app/models/course_enrollment.rb', line 46

belongs_to :course, optional: true

#course_categoriesActiveRecord::Relation<CourseCategory>

Returns category assignments for this enrollment.

Returns:

  • (ActiveRecord::Relation<CourseCategory>)

    category assignments for this enrollment



52
# File 'app/models/course_enrollment.rb', line 52

has_many :course_categories, dependent: :delete_all

#course_examsActiveRecord::Relation<CourseExam>

Returns exams taken under this enrollment.

Returns:

  • (ActiveRecord::Relation<CourseExam>)

    exams taken under this enrollment



50
# File 'app/models/course_enrollment.rb', line 50

has_many :course_exams, dependent: :delete_all

#course_titleString

Returns the enrolled course title.

Returns:

  • (String)

    course title



139
140
141
# File 'app/models/course_enrollment.rb', line 139

def course_title
  course.name
end

#customer_topicsActiveRecord::Relation<CustomerTopic>

Returns assigned content topics.

Returns:

  • (ActiveRecord::Relation<CustomerTopic>)

    assigned content topics



54
# File 'app/models/course_enrollment.rb', line 54

has_many :customer_topics, dependent: :delete_all

#notify_failed_examvoid

This method returns an undefined value.

Enqueues the failed-exam notification.



198
199
200
# File 'app/models/course_enrollment.rb', line 198

def notify_failed_exam
  TrainingMailer.course_enrollment_exam(self, false).deliver_later
end

#notify_new_enrollmentvoid

This method returns an undefined value.

Enqueues the new-enrollment notification.



184
185
186
# File 'app/models/course_enrollment.rb', line 184

def notify_new_enrollment
  TrainingMailer.new_course_enrollment(self).deliver_later
end

#notify_successful_examvoid

This method returns an undefined value.

Enqueues the successful-exam notification.



191
192
193
# File 'app/models/course_enrollment.rb', line 191

def notify_successful_exam
  TrainingMailer.course_enrollment_exam(self, true).deliver_later
end

#partyParty?

Returns the enrolled customer.

Returns:

  • (Party, nil)

    the enrolled customer



48
# File 'app/models/course_enrollment.rb', line 48

belongs_to :party, optional: true, inverse_of: :course_enrollments

#passed?Boolean

Whether the enrollment is completed with at least one passed exam.

Returns:

  • (Boolean)


132
133
134
# File 'app/models/course_enrollment.rb', line 132

def passed?
  state == 'completed' && course_exams.where(state: 'passed').present?
end

#percentage_progressString?

Formats the current progress percentage for display.

Returns:

  • (String, nil)

    formatted percentage, or nil when progress is unavailable



98
99
100
101
# File 'app/models/course_enrollment.rb', line 98

def percentage_progress
  progress_value = progress
  "#{progress_value}%" if progress_value.present?
end

#progressInteger?

Completion is monotonic: a completed enrollment always reports 100%,
even if topics were assigned to it after completion (content sync or
manual assignment). The learner finished the course as it existed then.

Returns:

  • (Integer, nil)

    completion percentage, or nil when no content is assigned



89
90
91
92
93
# File 'app/models/course_enrollment.rb', line 89

def progress
  return 100 if completed?

  (customer_topics.completed.size * 100) / customer_topics.size if customer_topics.present?
end

#send_new_certificate_reminder_emailBoolean

Sends a certificate-request reminder and records its delivery request.

Returns:

  • (Boolean)

    whether the reminder fields were persisted



158
159
160
161
162
163
164
165
# File 'app/models/course_enrollment.rb', line 158

def send_new_certificate_reminder_email
  customer = party
  CommunicationBuilder.new(resource: self,
                                  recipient_party: customer,
                                  use_best_email: true,
                                  template_system_code: 'NEW_CERT_REMINDER').create
  update(passed_email_reminder_sent: true, passed_email_reminder_sent_at: Time.current)
end

#send_passed_emailBoolean

Sends the course-passed email and records its delivery request.

Returns:

  • (Boolean)

    whether the sent-at fields were persisted



146
147
148
149
150
151
152
153
# File 'app/models/course_enrollment.rb', line 146

def send_passed_email
  customer = party
  CommunicationBuilder.new(resource: self,
                                  recipient_party: customer,
                                  use_best_email: true,
                                  template_system_code: 'COURSE_EXAM_PASSED').create
  update(passed_email_sent: true, passed_email_sent_at: Time.current)
end

#send_progress_reminder(days) ⇒ Boolean?

Sends a progress reminder and records the corresponding milestone.

Parameters:

  • days (Integer)

    elapsed-day milestone to record

Returns:

  • (Boolean, nil)

    whether the milestone was persisted, or nil when unsupported



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'app/models/course_enrollment.rb', line 206

def send_progress_reminder(days)
  customer = party
  CommunicationBuilder.new(resource: self,
                                  recipient_party: customer,
                                  use_best_email: true,
                                  template_system_code: 'CERT_PROGRESS').create
  case days
  when 30
    update_columns(reminder_1: Time.current, reminder_2: nil, reminder_3: nil, reminder_4: nil)
  when 60
    update_columns(reminder_2: Time.current, reminder_3: nil, reminder_4: nil)
  when 90
    update_columns(reminder_3: Time.current, reminder_4: nil)
  when 120
    update_columns(reminder_4: Time.current)
  end
end

#statusString

Describes whether the enrollment is complete or still underway.

Returns:

  • (String)

    human-readable enrollment status



113
114
115
116
117
118
119
120
# File 'app/models/course_enrollment.rb', line 113

def status
  if completed?
    "Completed"
  else
    "Ongoing - #{percentage_progress}"
  end
  # There could also be state "renewed" or "expired"
end