-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
participant.rb
163 lines (142 loc) · 5.67 KB
/
participant.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
class Participant < ApplicationRecord
include Scoring
include ParticipantsHelper
has_paper_trail
belongs_to :user
belongs_to :topic, class_name: 'SignUpTopic', inverse_of: false
belongs_to :assignment, foreign_key: 'parent_id', inverse_of: false
has_many :join_team_requests, dependent: :destroy
has_many :reviews, class_name: 'ResponseMap', foreign_key: 'reviewer_id', dependent: :destroy, inverse_of: false
has_many :team_reviews, class_name: 'ReviewResponseMap', foreign_key: 'reviewer_id', dependent: :destroy, inverse_of: false
has_many :response_maps, class_name: 'ResponseMap', foreign_key: 'reviewee_id', dependent: :destroy, inverse_of: false
has_many :awarded_badges, dependent: :destroy
has_many :badges, through: :awarded_badges
has_one :review_grade, dependent: :destroy
validates :grade, numericality: { allow_nil: true }
has_paper_trail
delegate :course, to: :assignment
delegate :current_stage, to: :assignment
delegate :stage_deadline, to: :assignment
PARTICIPANT_TYPES = %w[Course Assignment].freeze
# define a constant to hold the duty title Mentor
# this will be used in the duty column of the participant
# table to define participants who can mentor teams, topics, or assignments
# since the column's type is VARCHAR(255), other string constants should be
# defined here to add different duty titles
DUTY_MENTOR = 'mentor'.freeze
def team
TeamsUser.find_by(user: user).try(:team)
end
def responses
response_maps.map(&:response)
end
def name(ip_address = nil)
user.name(ip_address)
end
def fullname(ip_address = nil)
user.fullname(ip_address)
end
def handle(ip_address = nil)
User.anonymized_view?(ip_address) ? 'handle' : self[:handle]
end
def delete(force = nil)
maps = ResponseMap.where('reviewee_id = ? or reviewer_id = ?', id, id)
raise 'Associations exist for this participant.' unless force || (maps.blank? && team.nil?)
force_delete(maps)
end
def force_delete(maps)
maps && maps.each(&:destroy)
if team && (team.teams_users.length == 1)
team.delete
elsif team
team.teams_users.each { |teams_user| teams_user.destroy if teams_user.user_id == id }
end
destroy
end
def topic_name
if topic.nil? || topic.topic_name.empty?
'<center>—</center>' # em dash
else
topic.topic_name
end
end
# send email to team's reviewers in case a new submission is made
def mail_assigned_reviewers
# Find review mappings for the work done by this participant's team
mappings = ResponseMap.where(reviewed_object_id: self.assignment.id,
reviewee_id: self.team.id,
type: 'ReviewResponseMap')
unless mappings.nil?
mappings.each do |mapping|
reviewer = mapping.reviewer.user
prepared_mail = MailerHelper.send_mail_to_assigned_reviewers(reviewer, self, mapping)
prepared_mail.deliver_now
end
end
end
def able_to_review
can_review
end
def email(pw, home_page)
user = User.find_by(id: user_id)
assignment = Assignment.find_by(id: self.assignment.id)
Mailer.sync_message(
recipients: user.email,
subject: "You have been registered as a participant in the Assignment #{assignment.name}",
body: {
home_page: home_page,
first_name: ApplicationHelper.get_user_first_name(user),
name: user.name,
password: pw,
partial_name: 'register'
}
).deliver
end
# Get authorization from permissions.
def authorization
authorization = 'participant'
authorization = 'reader' if !can_submit && can_review && can_take_quiz
authorization = 'submitter' if can_submit && !can_review && !can_take_quiz
authorization = 'reviewer' if !can_submit && can_review && !can_take_quiz
authorization
end
def teammate_review_allowed
# time when teammate review is allowed
due_date = assignment.current_due_date
assignment.find_current_stage == 'Finished' ||
due_date &&
(due_date.teammate_review_allowed_id == 3 ||
due_date.teammate_review_allowed_id == 2) # late(2) or yes(3)
end
# Sort a set of participants based on their user names.
# Please make sure there is no duplicated participant in this input array.
# There should be a more beautiful way to handle this, though. -Yang
def self.sort_by_name(participants)
users = []
participants.each { |p| users << p.user }
users.sort! { |a, b| a.name.downcase <=> b.name.downcase } # Sort the users based on the name
participants.sort_by { |p| users.map(&:id).index(p.user_id) }
end
# provide export functionality for Assignment Participants and Course Participants
def self.export(csv, parent_id, options)
where(parent_id: parent_id).find_each do |part|
tcsv = []
user = part.user
tcsv.push(user.name, user.fullname, user.email) if options['personal_details'] == 'true'
tcsv.push(user.role.name) if options['role'] == 'true'
tcsv.push(user.parent.name) if options['parent'] == 'true'
tcsv.push(user.email_on_submission, user.email_on_review, user.email_on_review_of_review) if options['email_options'] == 'true'
tcsv.push(part.handle) if options['handle'] == 'true'
csv << tcsv
end
end
def self.export_fields(options)
fields = []
fields.push('name', 'full name', 'email') if options['personal_details'] == 'true'
fields.push('role') if options['role'] == 'true'
fields.push('parent') if options['parent'] == 'true'
fields.push('email on submission', 'email on review', 'email on metareview') if options['email_options'] == 'true'
fields.push('handle') if options['handle'] == 'true'
fields
end
end