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.
413 lines
12 KiB
413 lines
12 KiB
class User < ApplicationRecord
|
|
# Include default devise modules. Others available are:
|
|
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
|
devise :database_authenticatable,
|
|
:registerable,
|
|
:recoverable,
|
|
:rememberable,
|
|
:validatable,
|
|
:confirmable
|
|
|
|
has_many :entries, dependent: :destroy
|
|
|
|
PRAKTIKUMSTYPEN = %w[
|
|
propädeutikum
|
|
fachspezifikum
|
|
mediation
|
|
].freeze
|
|
|
|
# ------------------------------------------------------------
|
|
# Alle möglichen Entry-Arten
|
|
# ------------------------------------------------------------
|
|
ENTRY_ARTEN = [
|
|
# Allgemein
|
|
"Praktikum",
|
|
"Selbsterfahrung",
|
|
"Supervision",
|
|
"Fortbildung",
|
|
"Semesterkosten",
|
|
|
|
# Mediation
|
|
"Präsenzmodul",
|
|
"Peergruppenarbeit",
|
|
"Fallarbeit",
|
|
"Praxisseminare",
|
|
"Literatur- und Selbststudium",
|
|
|
|
# Fachspezifikum
|
|
"Gruppenselbsterfahrung",
|
|
"Theorie/Methodikseminare",
|
|
"Peergruppensupervision",
|
|
"Einzel-/Kleingruppensupervision",
|
|
"Eigenständige Tätigkeit"
|
|
].freeze
|
|
|
|
# ------------------------------------------------------------
|
|
# Arten pro Ausbildung
|
|
#
|
|
# Kann im Frontend / Controller verwendet werden, damit nicht
|
|
# jede Entry-Art bei jedem Ausbildungstyp angezeigt wird.
|
|
# ------------------------------------------------------------
|
|
ENTRY_ARTEN_BY_TYP = {
|
|
"propädeutikum" => [
|
|
"Praktikum",
|
|
"Selbsterfahrung",
|
|
"Supervision",
|
|
"Fortbildung",
|
|
"Semesterkosten"
|
|
],
|
|
|
|
"fachspezifikum" => [
|
|
"Praktikum",
|
|
"Selbsterfahrung",
|
|
"Supervision",
|
|
"Fortbildung",
|
|
"Semesterkosten",
|
|
"Gruppenselbsterfahrung",
|
|
"Theorie/Methodikseminare",
|
|
"Peergruppensupervision",
|
|
"Einzel-/Kleingruppensupervision",
|
|
"Eigenständige Tätigkeit"
|
|
],
|
|
|
|
"mediation" => [
|
|
"Präsenzmodul",
|
|
"Selbsterfahrung",
|
|
"Supervision",
|
|
"Peergruppenarbeit",
|
|
"Fallarbeit",
|
|
"Praxisseminare",
|
|
"Literatur- und Selbststudium",
|
|
"Fortbildung",
|
|
"Semesterkosten"
|
|
]
|
|
}.freeze
|
|
|
|
# ------------------------------------------------------------
|
|
# Mediation – zusätzliche Anforderungen
|
|
# ------------------------------------------------------------
|
|
|
|
# Vorgabe des konkreten Lehrgangs
|
|
MEDIATION_PRAESENZMODULE_TAGE = 19
|
|
|
|
# ZivMediat-AV:
|
|
# Von den insgesamt 26 Supervisionseinheiten müssen mindestens
|
|
# 3 Einheiten Einzelsupervision sein.
|
|
MEDIATION_EINZELSUPERVISION_MINDESTENS = 3
|
|
|
|
after_initialize :set_default, if: :new_record?
|
|
|
|
# ------------------------------------------------------------
|
|
# Allgemein
|
|
# ------------------------------------------------------------
|
|
|
|
def praepedeutikum_abgeschlossen?
|
|
praepedeutikum_done
|
|
end
|
|
|
|
def is_admin?
|
|
email == "christoph@marzell.net"
|
|
end
|
|
|
|
def self.entry_arten_for(typ)
|
|
ENTRY_ARTEN_BY_TYP[typ.to_s] || ENTRY_ARTEN
|
|
end
|
|
|
|
# ------------------------------------------------------------
|
|
# Matrizen aktualisieren
|
|
# ------------------------------------------------------------
|
|
|
|
def update_required_matrices!
|
|
required = (required_hours_matrix || {}).deep_stringify_keys
|
|
weekly = (weekly_target_matrix || {}).deep_stringify_keys
|
|
|
|
migrate_legacy_peer_group_key!(
|
|
required,
|
|
use_default_when_zero: true
|
|
)
|
|
|
|
migrate_legacy_peer_group_key!(
|
|
weekly,
|
|
use_default_when_zero: false
|
|
)
|
|
|
|
PRAKTIKUMSTYPEN.each do |typ|
|
|
required[typ] ||= {}
|
|
weekly[typ] ||= {}
|
|
|
|
ENTRY_ARTEN.each do |art|
|
|
unless required[typ].key?(art)
|
|
required[typ][art] = default_hours_for(typ, art)
|
|
end
|
|
|
|
unless weekly[typ].key?(art)
|
|
weekly[typ][art] = default_weekly_target_for(typ, art)
|
|
end
|
|
end
|
|
end
|
|
|
|
self.required_hours_matrix = required
|
|
self.weekly_target_matrix = weekly
|
|
|
|
save!
|
|
end
|
|
|
|
# ------------------------------------------------------------
|
|
# Default-Wochenziele
|
|
# ------------------------------------------------------------
|
|
|
|
def default_weekly_target_for(typ, art)
|
|
typ = typ.to_s
|
|
art = canonical_entry_art(art)
|
|
|
|
case [typ, art]
|
|
when ["propädeutikum", "Praktikum"]
|
|
12
|
|
|
|
when ["fachspezifikum", "Praktikum"]
|
|
10
|
|
|
|
when ["propädeutikum", "Selbsterfahrung"],
|
|
["fachspezifikum", "Selbsterfahrung"],
|
|
["fachspezifikum", "Gruppenselbsterfahrung"]
|
|
0.25
|
|
|
|
when ["propädeutikum", "Supervision"],
|
|
["fachspezifikum", "Supervision"],
|
|
["fachspezifikum", "Peergruppensupervision"],
|
|
["fachspezifikum", "Einzel-/Kleingruppensupervision"]
|
|
0.25
|
|
|
|
when ["fachspezifikum", "Eigenständige Tätigkeit"]
|
|
10
|
|
|
|
# Mediation findet typischerweise blockweise statt.
|
|
# Deshalb kein künstliches Wochenziel.
|
|
when ["mediation", "Präsenzmodul"],
|
|
["mediation", "Selbsterfahrung"],
|
|
["mediation", "Supervision"],
|
|
["mediation", "Peergruppenarbeit"],
|
|
["mediation", "Fallarbeit"],
|
|
["mediation", "Praxisseminare"],
|
|
["mediation", "Literatur- und Selbststudium"]
|
|
0
|
|
|
|
else
|
|
0
|
|
end
|
|
end
|
|
|
|
# ------------------------------------------------------------
|
|
# Default-Sollstunden / Einheiten
|
|
# ------------------------------------------------------------
|
|
|
|
def default_hours_for(typ, art)
|
|
typ = typ.to_s
|
|
art = canonical_entry_art(art)
|
|
|
|
case [typ, art]
|
|
# ----------------------------------------------------------
|
|
# Propädeutikum
|
|
# ----------------------------------------------------------
|
|
when ["propädeutikum", "Praktikum"]
|
|
480
|
|
|
|
when ["propädeutikum", "Selbsterfahrung"]
|
|
50
|
|
|
|
when ["propädeutikum", "Supervision"]
|
|
20
|
|
|
|
# ----------------------------------------------------------
|
|
# Fachspezifikum
|
|
# ----------------------------------------------------------
|
|
when ["fachspezifikum", "Praktikum"]
|
|
600
|
|
|
|
when ["fachspezifikum", "Selbsterfahrung"]
|
|
80
|
|
|
|
when ["fachspezifikum", "Supervision"]
|
|
40
|
|
|
|
when ["fachspezifikum", "Gruppenselbsterfahrung"]
|
|
64
|
|
|
|
when ["fachspezifikum", "Theorie/Methodikseminare"]
|
|
216
|
|
|
|
when ["fachspezifikum", "Peergruppensupervision"]
|
|
168
|
|
|
|
when ["fachspezifikum", "Einzel-/Kleingruppensupervision"]
|
|
40
|
|
|
|
when ["fachspezifikum", "Eigenständige Tätigkeit"]
|
|
600
|
|
|
|
# ----------------------------------------------------------
|
|
# Mediation
|
|
# ----------------------------------------------------------
|
|
|
|
# Wird in Tagen und nicht in Stunden bewertet.
|
|
when ["mediation", "Präsenzmodul"]
|
|
230
|
|
|
|
# ZivMediat-AV Anlage 1
|
|
when ["mediation", "Selbsterfahrung"]
|
|
40
|
|
|
|
when ["mediation", "Supervision"]
|
|
26
|
|
|
|
when ["mediation", "Peergruppenarbeit"]
|
|
24
|
|
|
|
when ["mediation", "Fallarbeit"]
|
|
17
|
|
|
|
when ["mediation", "Praxisseminare"]
|
|
58
|
|
|
|
# Zusätzliche Lehrgangsvorgabe
|
|
when ["mediation", "Literatur- und Selbststudium"]
|
|
150
|
|
|
|
else
|
|
0
|
|
end
|
|
end
|
|
|
|
# ------------------------------------------------------------
|
|
# Sollwert aus persönlicher Matrix
|
|
# ------------------------------------------------------------
|
|
|
|
def required_hours_for(typ, art)
|
|
typ = typ.to_s
|
|
art = canonical_entry_art(art)
|
|
|
|
value = required_hours_matrix&.dig(typ, art)
|
|
|
|
value.nil? ? default_hours_for(typ, art) : value
|
|
end
|
|
|
|
def weekly_target_for(typ, art)
|
|
typ = typ.to_s
|
|
art = canonical_entry_art(art)
|
|
|
|
value = weekly_target_matrix&.dig(typ, art)
|
|
|
|
value.nil? ? default_weekly_target_for(typ, art) : value
|
|
end
|
|
|
|
# ------------------------------------------------------------
|
|
# Mediation – Präsenztage
|
|
# ------------------------------------------------------------
|
|
|
|
def mediation_praesenzmodule_required
|
|
MEDIATION_PRAESENZMODULE_TAGE
|
|
end
|
|
|
|
def mediation_praesenzmodule_completed
|
|
entries
|
|
.where(
|
|
praktikums_typ: "mediation",
|
|
entry_art: "Präsenzmodul"
|
|
)
|
|
.distinct
|
|
.count(:date)
|
|
end
|
|
|
|
def mediation_praesenzmodule_remaining
|
|
[
|
|
mediation_praesenzmodule_required -
|
|
mediation_praesenzmodule_completed,
|
|
0
|
|
].max
|
|
end
|
|
|
|
def mediation_praesenzmodule_completed?
|
|
mediation_praesenzmodule_completed >=
|
|
mediation_praesenzmodule_required
|
|
end
|
|
|
|
# ------------------------------------------------------------
|
|
# Mediation – besondere Vorgaben
|
|
# ------------------------------------------------------------
|
|
|
|
def mediation_einzelsupervision_required
|
|
MEDIATION_EINZELSUPERVISION_MINDESTENS
|
|
end
|
|
|
|
private
|
|
|
|
# ------------------------------------------------------------
|
|
# Defaults für neuen User
|
|
# ------------------------------------------------------------
|
|
|
|
def set_default
|
|
self.required_hours_matrix ||= PRAKTIKUMSTYPEN.to_h do |typ|
|
|
[
|
|
typ,
|
|
ENTRY_ARTEN.to_h do |art|
|
|
[art, default_hours_for(typ, art)]
|
|
end
|
|
]
|
|
end
|
|
|
|
self.weekly_target_matrix ||= PRAKTIKUMSTYPEN.to_h do |typ|
|
|
[
|
|
typ,
|
|
ENTRY_ARTEN.to_h do |art|
|
|
[art, default_weekly_target_for(typ, art)]
|
|
end
|
|
]
|
|
end
|
|
end
|
|
|
|
# ------------------------------------------------------------
|
|
# Alte Bezeichnungen normalisieren
|
|
# ------------------------------------------------------------
|
|
|
|
def canonical_entry_art(art)
|
|
case art.to_s
|
|
when "Peergroup", "Peer-Gruppe"
|
|
"Peergruppenarbeit"
|
|
else
|
|
art.to_s
|
|
end
|
|
end
|
|
|
|
def migrate_legacy_peer_group_key!(matrix, use_default_when_zero:)
|
|
PRAKTIKUMSTYPEN.each do |typ|
|
|
values = matrix[typ]
|
|
next unless values.is_a?(Hash)
|
|
|
|
legacy_value = nil
|
|
|
|
if values.key?("Peergroup")
|
|
legacy_value = values.delete("Peergroup")
|
|
end
|
|
|
|
if values.key?("Peer-Gruppe")
|
|
legacy_value ||= values.delete("Peer-Gruppe")
|
|
end
|
|
|
|
next if legacy_value.nil?
|
|
next if values.key?("Peergruppenarbeit")
|
|
|
|
if use_default_when_zero &&
|
|
typ == "mediation" &&
|
|
legacy_value.to_f.zero?
|
|
|
|
values["Peergruppenarbeit"] =
|
|
default_hours_for(
|
|
"mediation",
|
|
"Peergruppenarbeit"
|
|
)
|
|
else
|
|
values["Peergruppenarbeit"] = legacy_value
|
|
end
|
|
end
|
|
end
|
|
end
|