You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
4.9 KiB
125 lines
4.9 KiB
6 years ago
|
class Ecs::CalculateCourseEvaluationService < ApplicationService
|
||
|
attr_reader :ec_course
|
||
|
|
||
|
def initialize(ec_course)
|
||
|
@ec_course = ec_course
|
||
|
end
|
||
|
|
||
|
def call
|
||
|
ActiveRecord::Base.transaction do
|
||
|
clear_student_score!
|
||
|
|
||
|
calculate_student_score_target!
|
||
|
|
||
|
calculate_graduation_requirement!
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def clear_student_score!
|
||
|
ec_course.ec_course_student_scores.destroy_all
|
||
|
end
|
||
|
|
||
|
def requirement_passed?(standard_value, real_value)
|
||
|
standard_value && real_value && real_value >= standard_value ? 1 : 0
|
||
|
end
|
||
|
|
||
|
def calculate_student_score_target!
|
||
|
complete_target_count = 0
|
||
|
course_targets = ec_course.ec_course_targets.includes(ec_achievement_evaluation_relates: :ec_course_achievement_method)
|
||
|
course_targets.find_each do |target|
|
||
|
target.ec_achievement_evaluation_relates.each do |relate|
|
||
|
achievement_method = relate.ec_course_achievement_method
|
||
|
|
||
|
total = achievement_method.ec_achievement_evaluation_relates.count
|
||
|
percentage = total.zero? ? 0 : achievement_method.percentage.fdiv(total)
|
||
|
|
||
|
achievements = EcStudentAchievement.where(ec_course_evaluation_id: achievement_method.ec_course_evaluation_id)
|
||
|
|
||
|
achievements =
|
||
|
if relate.ec_course_evaluation_subitem_id.blank? || relate.ec_course_evaluation_subitem_id == -1
|
||
|
achievements.where(position: relate.position)
|
||
|
else
|
||
|
achievements.where(ec_course_evaluation_subitem_id: relate.ec_course_evaluation_subitem_id)
|
||
|
end
|
||
|
|
||
|
# 遍历学生成绩统计数据
|
||
|
achievements.find_each do |achievement|
|
||
|
student_score = EcCourseStudentScore.find_or_initialize_by(
|
||
|
ec_course_id: ec_course.id,
|
||
|
ec_year_student_id: achievement.ec_year_student_id
|
||
|
)
|
||
|
|
||
|
score = achievement_method.score.zero? || achievement.score.nil? ? 0 : (achievement.fdiv(achievement_method.score) * percentage).round(3)
|
||
|
|
||
|
if student_score.new_record?
|
||
|
student_score.student_name = achievement.student_name
|
||
|
student_score.student_number = achievement.student_number
|
||
|
student_score.save!
|
||
|
|
||
|
create_params = {
|
||
|
ec_course_id: ec_course.id, ec_year_student_id: achievement.ec_year_student_id,
|
||
|
ec_course_target_id: target.id, eaer_id: relate.id,
|
||
|
ec_target_position: target.position, score: score
|
||
|
}
|
||
|
student_score.ec_student_score_targets.create!(create_params)
|
||
|
else
|
||
|
score_target = EcStudentScoreTarget.find_or_initialize_by(
|
||
|
ec_course_id: ec_course.id,
|
||
|
ec_year_student_id: achievement.ec_year_student_id,
|
||
|
ec_course_student_score_id: student_score.id,
|
||
|
ec_course_target_id: target.id,
|
||
|
ec_target_position: target.position,
|
||
|
eaer_id: relate.id
|
||
|
)
|
||
|
|
||
|
score_target.score = score_target.score.to_f + score
|
||
|
score_target.save!
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# 计算该课程目标是否完成
|
||
|
count = target.ec_student_score_targets.count
|
||
|
score = target.ec_student_score_targets.sum(:score)
|
||
|
average = count.zero? ? 0 : score.fdiv(count)
|
||
|
complete_target_count += 1 if target.standard_grade && target.standard_grade <= average
|
||
|
end
|
||
|
|
||
|
ec_course.update!(complete_target_count: complete_target_count)
|
||
|
end
|
||
|
|
||
|
def calculate_graduation_requirement!
|
||
|
student_scores = ec_course.ec_course_student_scores.joins(:ec_course_target).group(:ec_course_target_id)
|
||
|
student_scores = student_scores.select('AVG(score) as average_score, ec_course_target_id')
|
||
|
student_score_map = student_scores.group_by { |item| item.ec_course_target_id }
|
||
|
|
||
|
subitem_targets = ec_course.ec_graduation_subitem_course_targets.includes(:ec_graduation_subitem, :ec_course_target)
|
||
|
subitem_targets.group_by { |subitem_target| subitem_target.ec_graduation_subitem }.each do |subitem, subitem_target_arr|
|
||
|
support = subitem.ec_course_supports.find_by(ec_course_id: ec_course.id)
|
||
|
next if support.blank?
|
||
|
|
||
|
total_weight = 0.0
|
||
|
total_score = 0.0
|
||
|
subitem_target_arr.each do |subitem_target|
|
||
|
target = subitem_target.ec_course_target
|
||
|
student_score = student_score_map[target.id].first
|
||
|
|
||
|
total_weight += target.weigths.to_f
|
||
|
total_score += student_score.average_score.round(2) * target.weigths.to_f
|
||
|
end
|
||
|
|
||
|
target_value = support.weights.to_f * ec_course.ec_year.calculation_value.to_f
|
||
|
real_value = total_weight.zero? ? 0 : (total_score * support.weights.to_f) / (total_weight * 100)
|
||
|
|
||
|
cal = support.ec_graduation_requirement_calculation || support.build_ec_graduation_requirement_calculation
|
||
|
|
||
|
cal.target_value = target_value.round(3)
|
||
|
cal.real_value = real_value.round(3)
|
||
|
cal.status = requirement_passed?(target_value, real_value)
|
||
|
cal.save!
|
||
|
end
|
||
|
end
|
||
|
end
|