Commit 6c777788 authored by Kaspar Vollenweider's avatar Kaspar Vollenweider 👻
Browse files

Merge branch '448-refactoring-halfyear-feedback' into 'develop'

Resolve "Refactoring Halfyear Feedback"

Closes #448

See merge request !816
parents 79774bff 099d7eaa
Pipeline #28558 passed with stage
in 51 minutes and 28 seconds
......@@ -2,10 +2,18 @@ class Assignment < ApplicationRecord
include AssignmentCommon
include VolunteersGroupAndTandemStateUpdate
has_one :assignment_log
has_many :hours, as: :hourable
has_many :feedbacks, as: :feedbackable
has_many :trial_feedbacks, as: :trial_feedbackable
has_one :assignment_log
# Semester process relations
#
has_many :semester_feedbacks, dependent: :destroy
has_many :semester_process_volunteer_missions, dependent: :destroy
has_many :semester_process_volunteers, through: :semester_process_volunteer_missions
has_many :semester_processes, through: :semester_process_volunteers
validates :client_id, uniqueness: {
scope: :volunteer_id, message: I18n.t('assignment_exists')
......
......@@ -7,6 +7,12 @@ module GroupAssignmentCommon
belongs_to :group_offer, -> { with_deleted } # include imported deleted group offers
has_many :reminder_mailing_volunteers, as: :reminder_mailable, dependent: :destroy
has_many :semester_feedbacks, dependent: :destroy
has_many :semester_process_volunteer_missions, dependent: :destroy
has_many :semester_process_volunteers, through: :semester_process_volunteer_missions
has_many :semester_processes, through: :semester_process_volunteers
has_one :group_offer_category, through: :group_offer
has_one :creator, -> { with_deleted }, through: :group_offer
......
module MissionEitherOneRelation
extend ActiveSupport::Concern
included do
# relates to either Assignment or GroupAssignment (not GroupOffer!)
belongs_to :assignment, optional: true
belongs_to :group_assignment, optional: true
validate :validate_group_assignment_or_assignment_present
def mission=(mission)
if mission.class.name == 'Assignment'
self.assignment = mission
else
self.group_assignment = mission
end
end
def mission
group_assignment || assignment
end
private
def validate_group_assignment_or_assignment_present
if assignment.blank? && group_assignment.blank?
errors.add(:assignment, :insuficient_relation)
errors.add(:group_assignment, :insuficient_relation)
elsif assignment.present? && group_assignment.present?
errors.add(:assignment, :too_many_relations)
errors.add(:group_assignment, :too_many_relations)
end
end
end
end
......@@ -12,6 +12,8 @@ class Hour < ApplicationRecord
belongs_to :billing_expense, -> { with_deleted }, optional: true, inverse_of: 'hours'
belongs_to :certificate, optional: true
belongs_to :semester_process_volunteer, optional: true
validates :hours, presence: true, numericality: { greater_than: 0 }
validates :meeting_date, presence: true
validates :hourable, presence: true
......
class SemesterFeedback < ApplicationRecord
include MissionEitherOneRelation
belongs_to :author, -> { with_deleted }, class_name: 'User', inverse_of: 'semester_feedbacks'
belongs_to :semester_process_volunteer
has_one :semester_process, through: :semester_process_volunteer
has_one :volunteer, through: :semester_process_volunteer
end
class SemesterProcess < ApplicationRecord
belongs_to :creator, -> { with_deleted }, class_name: 'User', inverse_of: 'semester_processes'
belongs_to :mail_posted_by, -> { with_deleted }, class_name: 'User',
inverse_of: 'semester_process_mails_posted', optional: true
belongs_to :reminder_mail_posted_by, -> { with_deleted }, class_name: 'User',
inverse_of: 'semester_process_reminder_mail_posted', optional: true
has_many :semester_process_volunteers, dependent: :destroy
has_many :volunteers, through: :semester_process_volunteers
has_many :semester_feedbacks, through: :semester_process_volunteers
has_many :hours, through: :semester_process_volunteers
has_many :semester_process_volunteer_missions, through: :semester_process_volunteers
has_many :semester_process_mails, through: :semester_process_volunteers
def mails
semester_process_mails.where(kind: 'mail')
end
def reminders
semester_process_mails.where(kind: 'reminder')
end
# will only return an array, not a AD-result
delegate :missions, to: :semester_process_volunteers
end
class SemesterProcessMail < ApplicationRecord
belongs_to :semester_process_volunteer
belongs_to :sent_by, class_name: 'User', inverse_of: 'semester_process_mails'
enum kind: { mail: 0, reminder: 1 }
scope :mail, -> { where(kind: 'mail') }
scope :reminder, -> { where(kind: 'reminder') }
end
class SemesterProcessVolunteer < ApplicationRecord
belongs_to :volunteer
belongs_to :semester_process
belongs_to :responsible, -> { with_deleted }, class_name: 'User',
inverse_of: 'semester_processes', optional: true
belongs_to :reviewed_by, -> { with_deleted }, class_name: 'User',
inverse_of: 'semester_processes', optional: true
belongs_to :commited_by, -> { with_deleted }, class_name: 'User',
inverse_of: 'semester_processes', optional: true
has_many :semester_process_volunteer_missions, dependent: :destroy
has_many :assignments, through: :semester_process_volunteer_missions
has_many :group_assignments, through: :semester_process_volunteer_missions
has_many :semester_feedbacks, dependent: :destroy
has_many :hours, dependent: :nullify
has_many :semester_process_mails, dependent: :destroy
has_many :mails, -> { where(kind: 'mail') }, class_name: 'SemesterProcessMail',
foreign_key: 'semester_process_volunteer_id', inverse_of: 'semester_process_volunteer'
has_many :reminders, -> { where(kind: 'reminder') }, class_name: 'SemesterProcessMail',
foreign_key: 'semester_process_volunteer_id', inverse_of: 'semester_process_volunteer'
# will only return an array, not a AD-result
def missions
assignments + group_assignments
end
end
class SemesterProcessVolunteerMission < ApplicationRecord
include MissionEitherOneRelation
belongs_to :semester_process_volunteer
end
......@@ -79,7 +79,27 @@ class User < ApplicationRecord
has_many :mailing_processes_submitted, through: :mailing_volunteer_processes_submitted,
source: :process_submitted_by
has_many :semester_processes, inverse_of: 'creator', foreign_key: 'creator_id'
# Semester Process relations
#
has_many :semester_processes, inverse_of: 'creator', foreign_key: 'creator_id',
class_name: 'SemesterProcess', dependent: :destroy
has_many :semester_process_mails_posted, inverse_of: 'mail_posted_by',
class_name: 'SemesterProcess', foreign_key: 'mail_posted_by_id', dependent: :nullify
has_many :semester_process_reminder_mail_posted, inverse_of: 'reminder_mail_posted_by',
class_name: 'SemesterProcess', foreign_key: 'reminder_mail_posted_by_id', dependent: :nullify
has_many :semester_process_mails, class_name: 'SemesterProcessMail', foreign_key: 'sent_by_id',
inverse_of: 'sent_by', dependent: :nullify
has_many :semester_process_reminders, -> { reminder }, through: :semester_process_mails
has_many :semester_process_responsibilities, inverse_of: 'responsible',
class_name: 'SemesterProcessVolunteer', foreign_key: 'responsible_id', dependent: :nullify
has_many :semester_process_reviews, inverse_of: 'reviewed_by',
class_name: 'SemesterProcessVolunteer', foreign_key: 'reviewed_by_id', dependent: :nullify
has_many :semester_process_commits, inverse_of: 'commited_by',
class_name: 'SemesterProcessVolunteer', foreign_key: 'commited_by_id', dependent: :nullify
has_many :semester_feedbacks, inverse_of: 'author', foreign_key: 'author_id', dependent: :destroy
has_and_belongs_to_many :department
......
......@@ -69,6 +69,13 @@ class Volunteer < ApplicationRecord
has_many :event_volunteers, dependent: :delete_all
has_many :events, through: :event_volunteers
# Semester Process relations
#
has_many :semester_process_volunteers, dependent: :destroy
has_many :semester_processes, through: :semester_process_volunteers
has_many :semester_feedbacks, through: :semester_process_volunteers
has_attached_file :avatar, styles: { thumb: '100x100#' }
# Validations
......
......@@ -441,10 +441,46 @@ de:
body: Text
subject: Betreff
semester_process:
period: Semester
period_start: Semester anfang
period_end: Semester ende
creator: Ersteller/in
<<: *id-generic_keys
semester: Semester
mail_subject_template: Mail Betreffs Vorlage
mail_body_template: Mail Vorlage
mail_posted_at: versendet am
mail_posted_by: versendet durch
reminder_mail_subject_template: Mahnungs Betreffs Vorlage
reminder_mail_body_template: Mahnungs Vorlage
reminder_mail_posted_at: versendet am
reminder_mail_posted_by: versendet durch
semester_process_volunteer:
<<: *id-generic_keys
commit_visited_at: Feedback Seite besucht am
commited_at: Bestätigt am
commited_by: Bestätigt durch
responsible: Übernommen durch
responsibility_taken_at: Übernommen am
reviewed_by: Quittiert durch
reviewed_at: Quittiert am
notes: Notizen
semester_process_mail:
<<: *id-generic_keys
sent_by: versendet von
sent_at: versendet am
subject: Betreff
body: Text
kind: Email Typ
kinds:
mail: Semester Email
reminder: Mahnungs Email
semester_process_volunteer_mission:
<<: *id-generic_keys
semester_feedback:
<<: *id-generic_keys
author: Author
goals: Ziele
achievements: Erfolge
future: Zukunft
comments: Kommentare
conversation: Rückmeldung erwünscht
user:
<<: *id-generic_keys
clients: Kunden/innen
......@@ -538,6 +574,12 @@ de:
attributes:
volunteer:
required: muss ausgewählt werden.
semester_process_volunteer_mission:
attributes:
assignment: &id-mission-relation-insuficient
insuficient_relation: Es wird mindestens ein Assignment oder GroupAssignment benötigt
too_many_relations: Es darf nur ein Assignment oder ein GroupAssignment verbunden werden
group_assignment: *id-mission-relation-insuficient
models:
assignment: Begleitung
feedback: Halbjahres-Rapport
......@@ -560,6 +602,10 @@ de:
relative: Verwante/r
reminder_mailing: Erinnerungs-Mailing
semester_process: Semester Prozess
semester_process_volunteer: Freiwillige/r
semester_process_mail: Semester Email
semester_process_volunteer_mission: Einsatz
semester_feedback: Semester Feedback
trial_feedback: Probezeit Feedback
user: Benutzer/in
volunteer: Freiwillige/n
......@@ -985,6 +1031,11 @@ de:
skills: Berufliche Kompetenzen, die Sie einbringen könnten?
strengths: Welche Stärken oder Kompetenzen (sozial, beruflich) könnten Sie in Ihre Freiwilligenarbeit einbringen?
external: Als externen Freiwilligen registrieren?
semester_feedback:
achievements: Was konnte in den letzten Monaten erreicht werden?
conversation: Ich wünsche ein Gespräch mit meiner/meinem Freiwilligenverantwortlichen.
future: Soll der Einsatz weiterlaufen und wenn ja, mit welchen Inhalten (Zielen)?
goals: Was waren die wichtigsten Inhalte (oder Ziele) Ihres Einsatzes in den letzten Monaten?
"no": 'Nein'
options:
certificate:
......
class CreateSemesterProcessVolunteers < ActiveRecord::Migration[5.1]
def change
create_table :semester_process_volunteers do |t|
t.references :volunteer, foreign_key: true
t.references :semester_process, foreign_key: true
# volunteers "Bestätigen"
t.datetime :commit_visited_at
t.datetime :commited_at
t.references :commited_by, references: :users, index: true
# superadmins "Uebernehmen"
t.references :responsible, references: :users, index: true
t.datetime :responsibility_taken_at
# superadmins "Quittieren"
t.references :reviewed_by, references: :users, index: true
t.datetime :reviewed_at
# Superadmin takes notes
t.jsonb :notes
t.datetime :deleted_at, index: true
t.timestamps
end
end
end
class AddSemesterColumnToSemesterProcess < ActiveRecord::Migration[5.1]
def change
change_table :semester_processes do |t|
t.remove :period_start
t.remove :period_end
t.daterange :semester
t.string :mail_subject_template
t.text :mail_body_template
t.datetime :mail_posted_at
t.references :mail_posted_by, references: :users, index: true
t.string :reminder_mail_subject_template
t.text :reminder_mail_body_template
t.datetime :reminder_mail_posted_at
t.references :reminder_mail_posted_by, references: :users, index: true
end
end
end
class CreateSemesterFeedbacks < ActiveRecord::Migration[5.1]
def change
create_table :semester_feedbacks do |t|
t.references :author, references: :users, index: true
t.references :semester_process_volunteer, index: false
# for relations to either Assignment or GroupAssignment (not GroupOffer!)
t.references :assignment, foreign_key: true
t.references :group_assignment, foreign_key: true
t.text :goals
t.text :achievements
t.text :future
t.text :comments
t.boolean :conversation, default: false
t.datetime :deleted_at, index: true
t.timestamps
end
end
end
class CreateSemesterProcessMails < ActiveRecord::Migration[5.1]
def change
create_table :semester_process_mails do |t|
t.references :semester_process_volunteer, foreign_key: true
t.references :sent_by, references: :users, index: true
t.datetime :sent_at
t.string :subject
t.text :body
t.integer :kind, default: 0
t.datetime :deleted_at, index: true
t.timestamps
end
end
end
class CreateSemesterProcessVolunteerMissions < ActiveRecord::Migration[5.1]
def change
create_table :semester_process_volunteer_missions do |t|
t.references :semester_process_volunteer, foreign_key: true,
index: { name: 'semester_proc_volunteer_mission_index' }
# can be either Assignment or GroupAssignment (not GroupOffer!)
t.references :assignment, foreign_key: true,
index: { name: 'semester_proc_volunteer_mission_assignment_index' }
t.references :group_assignment, foreign_key: true,
index: { name: 'semester_proc_volunteer_mission_group_assignment_index' }
t.datetime :deleted_at, index: true
t.timestamps
end
end
end
class AddRelationBetweenSemesterProcessAndHour < ActiveRecord::Migration[5.1]
def change
change_table :hours do |t|
t.references :semester_process_volunteer, foreign_key: true
end
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20181004121332) do
ActiveRecord::Schema.define(version: 20181004163636) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -284,7 +284,7 @@ ActiveRecord::Schema.define(version: 20181004121332) do
end
create_table "events", force: :cascade do |t|
t.integer "kind", null: false
t.integer "kind"
t.date "date"
t.time "start_time"
t.time "end_time"
......@@ -489,11 +489,13 @@ ActiveRecord::Schema.define(version: 20181004121332) do
t.string "hourable_type"
t.bigint "hourable_id"
t.bigint "reviewer_id"
t.bigint "semester_process_volunteer_id"
t.index ["billing_expense_id"], name: "index_hours_on_billing_expense_id"
t.index ["deleted_at"], name: "index_hours_on_deleted_at"
t.index ["hourable_type", "hourable_id"], name: "index_hours_on_hourable_type_and_hourable_id"
t.index ["meeting_date"], name: "index_hours_on_meeting_date"
t.index ["reviewer_id"], name: "index_hours_on_reviewer_id"
t.index ["semester_process_volunteer_id"], name: "index_hours_on_semester_process_volunteer_id"
t.index ["volunteer_id"], name: "index_hours_on_volunteer_id"
end
......@@ -624,15 +626,93 @@ ActiveRecord::Schema.define(version: 20181004121332) do
t.index ["deleted_at"], name: "index_reminder_mailings_on_deleted_at"
end
create_table "semester_feedbacks", force: :cascade do |t|
t.bigint "author_id"
t.bigint "semester_process_volunteer_id"
t.bigint "assignment_id"
t.bigint "group_assignment_id"
t.text "goals"
t.text "achievements"
t.text "future"
t.text "comments"
t.boolean "conversation", default: false
t.datetime "deleted_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["assignment_id"], name: "index_semester_feedbacks_on_assignment_id"
t.index ["author_id"], name: "index_semester_feedbacks_on_author_id"
t.index ["deleted_at"], name: "index_semester_feedbacks_on_deleted_at"
t.index ["group_assignment_id"], name: "index_semester_feedbacks_on_group_assignment_id"
end
create_table "semester_process_mails", force: :cascade do |t|
t.bigint "semester_process_volunteer_id"
t.bigint "sent_by_id"
t.datetime "sent_at"
t.string "subject"
t.text "body"
t.integer "kind", default: 0
t.datetime "deleted_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["deleted_at"], name: "index_semester_process_mails_on_deleted_at"
t.index ["semester_process_volunteer_id"], name: "index_semester_process_mails_on_semester_process_volunteer_id"
t.index ["sent_by_id"], name: "index_semester_process_mails_on_sent_by_id"
end
create_table "semester_process_volunteer_missions", force: :cascade do |t|
t.bigint "semester_process_volunteer_id"
t.bigint "assignment_id"
t.bigint "group_assignment_id"
t.datetime "deleted_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["assignment_id"], name: "semester_proc_volunteer_mission_assignment_index"
t.index ["deleted_at"], name: "index_semester_process_volunteer_missions_on_deleted_at"
t.index ["group_assignment_id"], name: "semester_proc_volunteer_mission_group_assignment_index"
t.index ["semester_process_volunteer_id"], name: "semester_proc_volunteer_mission_index"
end
create_table "semester_process_volunteers", force: :cascade do |t|
t.bigint "volunteer_id"
t.bigint "semester_process_id"
t.datetime "commit_visited_at"
t.datetime "commited_at"
t.bigint "commited_by_id"
t.bigint "responsible_id"
t.datetime "responsibility_taken_at"
t.bigint "reviewed_by_id"
t.datetime "reviewed_at"
t.jsonb "notes"
t.datetime "deleted_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["commited_by_id"], name: "index_semester_process_volunteers_on_commited_by_id"
t.index ["deleted_at"], name: "index_semester_process_volunteers_on_deleted_at"
t.index ["responsible_id"], name: "index_semester_process_volunteers_on_responsible_id"
t.index ["reviewed_by_id"], name: "index_semester_process_volunteers_on_reviewed_by_id"
t.index ["semester_process_id"], name: "index_semester_process_volunteers_on_semester_process_id"
t.index ["volunteer_id"], name: "index_semester_process_volunteers_on_volunteer_id"
end
create_table "semester_processes", force: :cascade do |t|
t.bigint "creator_id"
t.datetime "period_start"
t.datetime "period_end"
t.datetime "deleted_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.daterange "semester"
t.string "mail_subject_template"
t.text "mail_body_template"
t.datetime "mail_posted_at"
t.bigint "mail_posted_by_id"
t.string "reminder_mail_subject_template"
t.text "reminder_mail_body_template"
t.datetime "reminder_mail_posted_at"
t.bigint "reminder_mail_posted_by_id"
t.index ["creator_id"], name: "index_semester_processes_on_creator_id"
t.index ["deleted_at"], name: "index_semester_processes_on_deleted_at"
t.index ["mail_posted_by_id"], name: "index_semester_processes_on_mail_posted_by_id"
t.index ["reminder_mail_posted_by_id"], name: "index_semester_processes_on_reminder_mail_posted_by_id"
end
create_table "trial_feedbacks", force: :cascade do |t|
......@@ -775,10 +855,19 @@ ActiveRecord::Schema.define(version: 20181004121332) do
add_foreign_key "group_offers", "departments"
add_foreign_key "group_offers", "group_offer_categories"
add_foreign_key "hours", "billing_expenses"
add_foreign_key "hours", "semester_process_volunteers"
add_foreign_key "journals", "assignments"
add_foreign_key "journals", "users"
add_foreign_key "performance_reports", "users"
add_foreign_key "profiles", "users"
add_foreign_key "semester_feedbacks", "assignments"
add_foreign_key "semester_feedbacks", "group_assignments"
add_foreign_key "semester_process_mails", "semester_process_volunteers"
add_foreign_key "semester_process_volunteer_missions", "assignments"
add_foreign_key "semester_process_volunteer_missions", "group_assignments"
add_foreign_key "semester_process_volunteer_missions", "semester_process_volunteers"
add_foreign_key "semester_process_volunteers", "semester_processes"
add_foreign_key "semester_process_volunteers", "volunteers"
add_foreign_key "trial_feedbacks", "users", column: "author_id"
add_foreign_key "volunteers", "departments"
add_foreign_key "volunteers", "users"
......
FactoryBot.define do
factory :semester_feedback do
semester_process_volunteer
goals 'Goals text'
achievements 'Achievements text'
future 'Future text'
comments 'Comments text'
transient do
add_mission { true }
end
# feedback has to be created with mission, and then the resulting instance has it removed
# because otherwise test/models/factory_test.rb will fail
trait :no_mission do
add_mission { false }
end
trait :with_assignment do
association :assignment
end
trait :with_group_assignment do
association :group_assignment
end
after(:build) do |sem_fb, evl|
if sem_fb.assignment.blank?
sem_fb.group_assignment ||= FactoryBot.build(:group_assignment, volunteer: sem_fb.volunteer)
end
sem_fb.volunteer = sem_fb.semester_process_volunteer.volunteer
sem_fb.author = sem_fb.volunteer.user
end
after(:create) do |sem_fb, evl|
unless evl.add_mission
sem_fb.group_assignment = nil
sem_fb.assignment = nil
end
end
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment