class AttendanceStatisticsService < ApplicationService attr_reader :attendances, :member_attendances def initialize(attendances, member_attendances) @attendances = attendances @member_attendances = member_attendances end def call all_normal_rate = [] all_absence_rate = [] all_leave_rate = [] history_attendances = [] attendances.each do |attendance| normal_count = history_member_count(member_attendances, "NORMAL", attendance.id) absence_count = history_member_count(member_attendances, "ABSENCE", attendance.id) leave_count = history_member_count(member_attendances, "LEAVE", attendance.id) all_count = member_attendances.select{|member_attendance| member_attendance.course_attendance_id == attendance.id}.size normal_rate = all_count == 0 ? 1 : cal_rate(normal_count, all_count) all_normal_rate << normal_rate absence_rate = cal_rate(absence_count, all_count) all_absence_rate << absence_rate leave_rate = cal_rate(leave_count, all_count) all_leave_rate << leave_rate history_attendances << {name: attendance.name, attendance_date: attendance.attendance_date.strftime("%Y-%m-%d"), start_time: attendance.start_time.strftime("%H:%M"), end_time: attendance.end_time.strftime("%H:%M"), normal_rate: normal_rate, absence_rate: absence_rate, leave_rate: leave_rate} end all_history_count = history_attendances.size history_attendances = history_attendances[0..9].reverse avg_normal_rate = all_history_count == 0 ? 1 : cal_rate(all_normal_rate.sum, all_history_count) avg_absence_rate = cal_rate(all_absence_rate.sum, all_history_count) avg_leave_rate = cal_rate(all_leave_rate.sum, all_history_count) {all_history_count: all_history_count, history_attendances: history_attendances, avg_normal_rate: avg_normal_rate, avg_absence_rate: avg_absence_rate, avg_leave_rate: avg_leave_rate} end private def history_member_count member_attendances, status, attendance_id member_attendances.select{|member_attendance| member_attendance.attendance_status == status && member_attendance.course_attendance_id == attendance_id}.size end def cal_rate base, sum sum == 0 ? 0 : (base.to_f / sum) end end