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.
54 lines
3.3 KiB
54 lines
3.3 KiB
module Api
|
|
module V1
|
|
class DashboardController < BaseController
|
|
def show
|
|
current_user.update_required_matrices!
|
|
entries = current_user.entries.where("date <= ?", Date.current)
|
|
enabled_types = current_user.enabled_praktikums_typen_list
|
|
progress = enabled_types.flat_map do |typ|
|
|
User.entry_arten_for(typ).map do |art|
|
|
spent = entries.where(praktikums_typ: typ, entry_art: art).sum("COALESCE(hours, 0) * 60 + COALESCE(minutes, 0)").to_i
|
|
target = current_user.required_hours_for(typ, art).to_f * 60
|
|
remaining = [target - spent, 0].max.to_i
|
|
weekly_target = current_user.weekly_target_for(typ, art).to_f
|
|
dates = entries.where(praktikums_typ: typ, entry_art: art).where("COALESCE(hours, 0) > 0 OR COALESCE(minutes, 0) > 0")
|
|
first_date = dates.minimum(:date)
|
|
last_date = dates.maximum(:date)
|
|
period_end = spent >= target && last_date ? last_date : Date.current
|
|
weeks = first_date ? [[(period_end - first_date).to_i + 1, 7].max / 7.0, 1].max : nil
|
|
actual_weekly = weeks ? ((spent / 60.0) / weeks).round(2) : nil
|
|
estimated_end = weekly_target.positive? && remaining.positive? ? Date.current + (remaining / 60.0 / weekly_target).ceil.weeks : nil
|
|
{ typ:, art:, spent_minutes: spent, target_minutes: target.to_i, remaining_minutes: remaining,
|
|
percent: target.positive? ? [(spent / target * 100).round(1), 100].min : 0,
|
|
weekly_target:, actual_weekly:, estimated_end: }
|
|
end
|
|
end
|
|
total_spent = progress.sum { |row| row[:spent_minutes] }
|
|
total_target = progress.sum { |row| row[:target_minutes] }
|
|
render json: { total_minutes: total_spent, target_minutes: total_target, remaining_minutes: [total_target - total_spent, 0].max,
|
|
completed_percent: total_target.positive? ? (total_spent.to_f / total_target * 100).round(1) : 0,
|
|
total_distance_km: current_user.entries.sum(:distance_km), costs_by_year: costs_by_year,
|
|
running_entry: current_user.entries.find_by(end_time: nil, beschreibung: "Timer"),
|
|
enabled_praktikums_typen: enabled_types,
|
|
mediation_presence_days: current_user.mediation_praesenzmodule_completed,
|
|
mediation_presence_days_required: current_user.mediation_praesenzmodule_required,
|
|
last_entry: current_user.entries.where("date <= ?", Date.current).order(date: :desc).first, progress: }
|
|
end
|
|
|
|
private
|
|
|
|
def costs_by_year
|
|
years = current_user.entries.pluck(Arel.sql("DISTINCT EXTRACT(YEAR FROM date)::int")).compact.sort.reverse
|
|
km = Entry.total_kilometer_cost_by_year(current_user)
|
|
total = Entry.total_gesamtkosten_by_year(current_user)
|
|
training = Entry.total_fortbildungskosten_by_year(current_user)
|
|
experience = Entry.total_selbsterfahrungskosten_by_year(current_user)
|
|
supervision = Entry.total_supervision_by_year(current_user)
|
|
semester = Entry.total_semesterkosten_by_year(current_user)
|
|
years.map { |year| { year:, kilometer: km[year].to_f, fortbildung: training[year].to_f,
|
|
selbsterfahrung: experience[year].to_f, supervision: supervision[year].to_f,
|
|
semester: semester[year].to_f, total: total[year].to_f } }
|
|
end
|
|
end
|
|
end
|
|
end
|