1 changed files with 119 additions and 86 deletions
@ -1,88 +1,121 @@ |
|||
class Entry < ApplicationRecord |
|||
|
|||
require 'csv' |
|||
|
|||
|
|||
belongs_to :user |
|||
|
|||
validates :date, :hours, :minutes, presence: true |
|||
validates :hours, numericality: { only_integer: true, greater_than_or_equal_to: 0 } |
|||
validates :minutes, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than: 60 } |
|||
|
|||
before_save :normalize_time |
|||
|
|||
PRAKTIKUMSTYPEN = %w[propädeutikum fachspezifikum] |
|||
ENTRY_ARTEN = %w[Praktikum Selbsterfahrung Supervision Fortbildung Semesterkosten] |
|||
|
|||
validates :praktikums_typ, inclusion: { in: PRAKTIKUMSTYPEN } |
|||
validates :entry_art, inclusion: { in: ENTRY_ARTEN } |
|||
validates :distance_km, numericality: { only_integer: true, greater_than_or_equal_to: 0 } |
|||
|
|||
after_initialize :set_default_date, if: :new_record? |
|||
|
|||
def set_default_date |
|||
self.date ||= Date.today |
|||
end |
|||
|
|||
def kilometer_pauschale |
|||
return 0 unless distance_km.present? |
|||
distance_km * 0.42 |
|||
end |
|||
|
|||
def self.total_fortbildungskosten_by_year(user) |
|||
where(user: user, entry_art: 'Fortbildung') |
|||
.group_by { |e| e.date.year } |
|||
.transform_values { |entries| entries.sum { |e| e.kosten.to_f } } |
|||
end |
|||
|
|||
def self.total_selbsterfahrungskosten_by_year(user) |
|||
where(user: user, entry_art: 'Selbsterfahrung') |
|||
.group_by { |e| e.date.year } |
|||
.transform_values { |entries| entries.sum { |e| e.kosten.to_f } } |
|||
end |
|||
|
|||
def self.total_supervision_by_year(user) |
|||
where(user: user, entry_art: 'Supervision') |
|||
.group_by { |e| e.date.year } |
|||
.transform_values { |entries| entries.sum { |e| e.kosten.to_f } } |
|||
end |
|||
|
|||
def self.total_semesterkosten_by_year(user) |
|||
where(user: user) |
|||
.group_by { |e| e.date.year } |
|||
.transform_values { |entries| entries.sum { |e| e.kosten.to_f } } |
|||
end |
|||
|
|||
def jahr |
|||
date.year |
|||
end |
|||
|
|||
def total_minutes |
|||
hours * 60 + minutes |
|||
end |
|||
def self.to_csv |
|||
CSV.generate(headers: true, col_sep: ";") do |csv| |
|||
csv << %w[Datum Stunden Minuten Typ Art Kilometer User] |
|||
|
|||
all.each do |entry| |
|||
csv << [ |
|||
entry.date, |
|||
entry.hours, |
|||
entry.minutes, |
|||
entry.praktikums_typ, |
|||
entry.entry_art, |
|||
entry.distance_km, |
|||
entry.beschreibung, |
|||
entry.kosten, |
|||
entry.user.email |
|||
] |
|||
end |
|||
end |
|||
end |
|||
private |
|||
|
|||
def normalize_time |
|||
self.hours += minutes / 60 |
|||
self.minutes = minutes % 60 |
|||
end |
|||
require 'csv' |
|||
|
|||
belongs_to :user |
|||
|
|||
validates :date, :hours, :minutes, presence: true |
|||
validates :hours, numericality: { only_integer: true, greater_than_or_equal_to: 0 } |
|||
validates :minutes, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than: 60 } |
|||
|
|||
before_save :normalize_time |
|||
|
|||
PRAKTIKUMSTYPEN = %w[propädeutikum fachspezifikum] |
|||
ENTRY_ARTEN = %w[Praktikum Selbsterfahrung Supervision Fortbildung Semesterkosten] |
|||
|
|||
validates :praktikums_typ, inclusion: { in: PRAKTIKUMSTYPEN } |
|||
validates :entry_art, inclusion: { in: ENTRY_ARTEN } |
|||
validates :distance_km, numericality: { only_integer: true, greater_than_or_equal_to: 0 } |
|||
|
|||
after_initialize :set_default_date, if: :new_record? |
|||
|
|||
def set_default_date |
|||
self.date ||= Date.today |
|||
end |
|||
|
|||
def kilometer_pauschale |
|||
return 0 unless distance_km.present? |
|||
distance_km * 0.42 |
|||
end |
|||
|
|||
def self.total_kilometer_cost_by_year(user) |
|||
where(user: user) |
|||
.where.not(distance_km: nil) |
|||
.group(Arel.sql("DATE_PART('year', date)")) |
|||
.order(Arel.sql("DATE_PART('year', date) DESC")) |
|||
.pluck( |
|||
Arel.sql("DATE_PART('year', date)::int"), |
|||
Arel.sql("SUM(distance_km * 2 * 0.42)") |
|||
).to_h |
|||
end |
|||
|
|||
def self.total_fortbildungskosten_by_year(user) |
|||
where(user: user, entry_art: 'Fortbildung') |
|||
.where.not(kosten: nil) |
|||
.group(Arel.sql("DATE_PART('year', date)")) |
|||
.order(Arel.sql("DATE_PART('year', date) DESC")) |
|||
.pluck(Arel.sql("DATE_PART('year', date)::int"), Arel.sql("SUM(kosten)")) |
|||
.to_h |
|||
end |
|||
|
|||
def self.total_selbsterfahrungskosten_by_year(user) |
|||
where(user: user, entry_art: 'Selbsterfahrung') |
|||
.where.not(kosten: nil) |
|||
.group(Arel.sql("DATE_PART('year', date)")) |
|||
.order(Arel.sql("DATE_PART('year', date) DESC")) |
|||
.pluck(Arel.sql("DATE_PART('year', date)::int"), Arel.sql("SUM(kosten)")) |
|||
.to_h |
|||
end |
|||
|
|||
def self.total_selbsterfahrungskosten_by_year(user) |
|||
where(user: user, entry_art: 'Selbsterfahrung') |
|||
.where.not(kosten: nil) |
|||
.group(Arel.sql("DATE_PART('year', date)")) |
|||
.order(Arel.sql("DATE_PART('year', date) DESC")) |
|||
.pluck(Arel.sql("DATE_PART('year', date)::int"), Arel.sql("SUM(kosten)")) |
|||
.to_h |
|||
end |
|||
|
|||
def self.total_supervision_by_year(user) |
|||
where(user: user, entry_art: 'Supervision') |
|||
.where.not(kosten: nil) |
|||
.group(Arel.sql("DATE_PART('year', date)")) |
|||
.order(Arel.sql("DATE_PART('year', date) DESC")) |
|||
.pluck(Arel.sql("DATE_PART('year', date)::int"), Arel.sql("SUM(kosten)")) |
|||
.to_h |
|||
end |
|||
|
|||
def self.total_semesterkosten_by_year(user) |
|||
where(user: user) |
|||
.where.not(kosten: nil) |
|||
.group(Arel.sql("DATE_PART('year', date)")) |
|||
.order(Arel.sql("DATE_PART('year', date) DESC")) |
|||
.pluck(Arel.sql("DATE_PART('year', date)::int"), Arel.sql("SUM(kosten)")) |
|||
.to_h |
|||
end |
|||
|
|||
def jahr |
|||
date.year |
|||
end |
|||
|
|||
def total_minutes |
|||
hours * 60 + minutes |
|||
end |
|||
|
|||
def self.to_csv |
|||
CSV.generate(headers: true, col_sep: ";") do |csv| |
|||
csv << %w[Datum Stunden Minuten Typ Art Kilometer User] |
|||
|
|||
all.each do |entry| |
|||
csv << [ |
|||
entry.date, |
|||
entry.hours, |
|||
entry.minutes, |
|||
entry.praktikums_typ, |
|||
entry.entry_art, |
|||
entry.distance_km, |
|||
entry.beschreibung, |
|||
entry.kosten, |
|||
entry.user.email |
|||
] |
|||
end |
|||
end |
|||
end |
|||
|
|||
private |
|||
|
|||
def normalize_time |
|||
self.hours += minutes / 60 |
|||
self.minutes = minutes % 60 |
|||
end |
|||
end |
|||
Loading…
Reference in new issue