Commit 6dfcbe3d authored by Kaspar Vollenweider's avatar Kaspar Vollenweider

Merge branch 'develop' into 'master'

Deploy 2019-03-19

See merge request !942
parents 730d905c d0add18a
Pipeline #40225 passed with stage
in 37 minutes and 34 seconds
......@@ -69,3 +69,7 @@ fieldset {
.checkbox + .checkbox-line {
margin-top: 0;
}
textarea.double-height {
min-height: 100px;
}
......@@ -35,7 +35,7 @@ class ReminderMailingsController < ApplicationController
else
redirect_to new_email_template_path,
notice: 'Sie müssen eine aktive E-Mailvorlage haben,
bevor Sie eine Beendigungs E-Mail erstellen können.'
bevor Sie eine Abschlussevaluations E-Mail erstellen können.'
end
authorize @reminder_mailing
end
......
......@@ -53,10 +53,10 @@ module ApplicationHelper
}, class: html_class }
end
def checkbox_toggle_collapse(f, field, collapse_selector, check_shows: true, label_html: nil, type: :boolean, disabled: false)
def checkbox_toggle_collapse(f, field, collapse_selector, check_shows: true, label_html: nil, type: :boolean, disabled: false, tabindex: nil)
input_html = { data: { collapse: collapse_selector, check_shows: check_shows },
class: 'checkbox-toggle-collapse',
disabled: disabled }
class: 'checkbox-toggle-collapse', disabled: disabled }
input_html.merge(tabindex: tabindex) if tabindex
f.input(field, type: type, input_html: input_html, label_html: label_html)
end
......
......@@ -31,10 +31,10 @@ class EmailTemplate < ApplicationRecord
{
signup: [],
assignment: [:Anrede, :Name, :EinsatzTitel, :FeedbackLink],
trial: ReminderMailing::TEMPLATE_VARNAMES,
termination: ReminderMailing::TEMPLATE_VARNAMES,
half_year_process_email: SemesterProcessMail.template_varnames[:mail],
half_year_process_overdue: SemesterProcessMail.template_varnames[:reminder]
trial: ReminderMailing.template_varnames(:trial_period).values,
termination: ReminderMailing.template_varnames(:termination).values,
half_year_process_email: ReminderMailing.template_varnames(:half_year_process_email).values,
half_year_process_overdue: ReminderMailing.template_varnames(:half_year_process_overdue).values
}
end
......
......@@ -16,7 +16,8 @@ class LanguageSkill < ApplicationRecord
}
def self.languages
@languages ||= I18n.t('language_names').map { |key, lang| [lang, key.to_s] }.sort
@languages ||= I18n.t('language_names').merge(I18n.t('language_names_customizations'))
.map { |key, lang| [lang, key.to_s] }.sort
end
......
class ReminderMailing < ApplicationRecord
before_update :remove_untoggled_volunteers
TEMPLATE_VARNAMES = [
:Anrede,
:Name,
:Einsatz,
:EinsatzStart,
:FeedbackLink,
:EmailAbsender,
:OnlinePlattformUrl
].freeze
# Key is method name, value is users variable %{FeedbackLink}
TEMPLATE_VARNAMES_GENERAL = {
anrede: :Anrede,
name: :Name,
einsatz: :Einsatz,
email_absender: :EmailAbsender,
online_plattform_url: :OnlinePlattformUrl
}.freeze
# method var_name pairs per reminder_mailing kind
TEMPLATE_VARNAMES = {
trial_period: {
einsatz_start: :EinsatzStart,
feedback_link_trial: :FeedbackLink
}.merge(TEMPLATE_VARNAMES_GENERAL),
termination: {
einsatz_start: :EinsatzStart,
feedback_link_termination: :FeedbackLink
}.merge(TEMPLATE_VARNAMES_GENERAL),
half_year_process_email: {
feedback_link_semester: :FeedbackLink
}.merge(TEMPLATE_VARNAMES_GENERAL),
half_year_process_overdue: {
feedback_link_semester: :FeedbackLink
}.merge(TEMPLATE_VARNAMES_GENERAL)
}.freeze
belongs_to :creator, -> { with_deleted }, class_name: 'User', inverse_of: 'reminder_mailings'
......@@ -26,7 +41,8 @@ class ReminderMailing < ApplicationRecord
source_type: 'GroupAssignment'
has_many :process_submitters, through: :reminder_mailing_volunteers, source: :process_submitted_by
enum kind: { trial_period: 1, termination: 2, half_year_process_email: 3, half_year_process_overdue: 4 }
enum kind: { trial_period: 1, termination: 2, half_year_process_email: 3, half_year_process_overdue: 4 }
ransacker :kind, formatter: ->(value) { kinds[value] }
validates :subject, presence: true
......@@ -35,6 +51,16 @@ class ReminderMailing < ApplicationRecord
validate :no_reminder_volunteer_present, unless: :reminder_volunteer_mailings_any?
validate :mailing_not_to_change_after_sent
before_update :remove_untoggled_volunteers
def self.template_varnames(kind_requested)
TEMPLATE_VARNAMES[kind_requested.to_sym]
end
def template_varnames
TEMPLATE_VARNAMES[kind.to_sym]
end
# setter generates relation to assignment/group_assignment and volunteer in one go
def reminder_mailing_volunteers=(reminder_mailable)
if [Assignment, GroupAssignment].include? reminder_mailable.first&.class
......
......@@ -71,6 +71,20 @@ class ReminderMailingVolunteer < ApplicationRecord
template % template_variables
end
def template_variables
template_variables = reminder_mailing.template_varnames.map do |method_name, var_name|
[var_name, send(method_name)]
end.to_h
template_variables.default = ''
template_variables
end
## template variable converters
#
# there needs to be a method with the name matching each value
# from ReminderMailing::TEMPLATE_VARNAMES
# Otherwise there will be a method missing error if that template variable is used
def anrede
I18n.t("salutation.#{volunteer.salutation}")
end
......@@ -95,30 +109,30 @@ class ReminderMailingVolunteer < ApplicationRecord
end
end
def template_variables
template_variables = ReminderMailing::TEMPLATE_VARNAMES.map do |varname|
[varname, send(varname.to_s.underscore)]
end.to_h
template_variables.default = ''
template_variables
end
def email_absender
"[#{reminder_mailing_creator_name}](mailto:"\
"#{reminder_mailing.creator.email})"
end
def reminder_mailing_creator_name
reminder_mailing.creator.profile&.contact&.natural_name ||
reminder_mailing.creator.email
def feedback_link_trial
"[Probezeit-Feedback erstellen](#{feedback_url})"
end
def feedback_link_termination
"[Abschlussevaluations-Feedback erstellen](#{feedback_url})"
end
def feedback_link
"[Halbjahres-Rapport erstellen](#{feedback_url})"
def feedback_link_semester
"[Halbjahres-Feedback erstellen](#{feedback_url})"
end
def online_plattform_url
"[Online-Plattform Url](#{Rails.application.routes.url_helpers.root_path})"
end
# template variable assisting methods
def reminder_mailing_creator_name
reminder_mailing.creator.profile&.contact&.natural_name ||
reminder_mailing.creator.email
end
end
......@@ -12,42 +12,60 @@ class SemesterProcessMail < ApplicationRecord
delegate :volunteer, to: :semester_process_volunteer
delegate :semester_process, to: :semester_process_volunteer
# Key is method name, value is users variable %{FeedbackLink}
TEMPLATE_VARNAMES_GENERAL = {
anrede: :Anrede,
name: :Name,
feedback_link: :FeedbackLink,
email_absender: :EmailAbsender,
online_plattform_url: :OnlinePlattformUrl,
semester_from_to_date: :SemesterAnfangUndEndDatum
}.freeze
TEMPLATE_VARNAMES = {
mail: TEMPLATE_VARNAMES_GENERAL,
reminder: TEMPLATE_VARNAMES_GENERAL
}.freeze
def self.template_varnames(kind = :mail)
TEMPLATE_VARNAMES[kind]
end
TEMPLATE_VARNAMES = [
:Anrede,
:Name,
:Einsatz,
:FeedbackLink,
:EmailAbsender,
:OnlinePlattformUrl
].freeze
def self.template_varnames
{
mail: TEMPLATE_VARNAMES,
reminder: TEMPLATE_VARNAMES
}
def template_varnames
TEMPLATE_VARNAMES[kind.to_sym]
end
def process_template
{
subject: replace_ruby_template(self.subject),
body: replace_ruby_template(self.body)
subject: replace_ruby_template(subject),
body: replace_ruby_template(body)
}
end
private
def send_email
VolunteerMailer.half_year_process_email(self).deliver
update!(sent_at: Time.zone.now)
end
def replace_ruby_template(template)
template % template_variables
end
def template_variables
template_variables = SemesterProcessMail::template_varnames[self.kind.to_sym].map do |varname|
[varname, send(varname.to_s.underscore)]
template_variables = template_varnames.map do |method_name, var_name|
[var_name, send(method_name)]
end.to_h
template_variables.default = ''
template_variables
end
## template variable converters
#
# there needs to be a method with the name matching each value
# from SemesterProcessMail::TEMPLATE_VARNAMES
# Otherwise there will be a method missing error if that template variable is used
def anrede
I18n.t("salutation.#{volunteer.salutation}")
end
......@@ -56,10 +74,6 @@ class SemesterProcessMail < ApplicationRecord
volunteer.contact.natural_name
end
def einsatz
''
end
def email_absender
"[#{reminder_mailing_creator_name}](mailto:"\
"#{semester_process.creator.email})"
......@@ -67,14 +81,14 @@ class SemesterProcessMail < ApplicationRecord
def reminder_mailing_creator_name
semester_process.creator.profile&.contact&.natural_name ||
semester_process.creator.email
semester_process.creator.email
end
def feedback_link
"[Halbjahres-Rapport erstellen](#{feedback_url})"
end
def feedback_url(options = {})
def feedback_url
Rails.application.routes.url_helpers.review_semester_review_semester_url(
semester_process_volunteer,
ActionMailer::Base.default_url_options
......@@ -85,10 +99,8 @@ class SemesterProcessMail < ApplicationRecord
"[Online-Plattform Url](#{Rails.application.routes.url_helpers.root_path})"
end
private
def send_email
VolunteerMailer.half_year_process_email(self).deliver
self.update(sent_at: Time.zone.now)
def semester_from_to_date
semester = semester_process_volunteer.semester
"#{I18n.l(semester.first)} bis #{I18n.l(semester.last)}}"
end
end
......@@ -52,13 +52,13 @@ hr
td= @assignment.hours.last&.hours || 0.0
- else
h2.m-t-20 Beendigung Abschliessen
h2.m-t-20 Abschlussevaluation Abschliessen
= simple_form_for(@assignment, url: update_terminated_at_assignment_path, method: :put) do |f|
.row
.col-xs-12.col-md-6
fieldset
legend Rückmeldungen zur Beendigung des Einsatzes
legend Rückmeldungen zur Abschlussevaluation des Einsatzes
= f.input :term_feedback_activities
= f.input :term_feedback_success
= f.input :term_feedback_problems
......
......@@ -11,23 +11,23 @@
.col-xs-12.col-md-6
fieldset
legend= t_attr(:personal_particulars, Contact)
= f.input :salutation, as: :select, collection: Client::SALUTATIONS, include_blank: true
= f.input :salutation, as: :select, collection: Client::SALUTATIONS, include_blank: true, input_html: { tabindex: 1 }
= f.simple_fields_for :contact do |c|
.row
.col-xs-12.col-md-6
= c.input :first_name, required: true
= c.input :first_name, required: true, input_html: { tabindex: 2 }
= f.input :birth_year, as: :select, collection: Client.year_collection,
include_blank: true
= f.input :entry_date
include_blank: true, input_html: { tabindex: 4 }
= f.input :entry_date, input_html: { tabindex: 6 }
.col-xs-12.col-md-6
= c.input :last_name, required: true, label: t_attr(:last_name)
= f.input :nationality, as: :country
= f.input :permit, collection: Client::PERMITS, as: :radio_buttons
= c.input :last_name, required: true, label: t_attr(:last_name), input_html: { tabindex: 3 }
= f.input :nationality, as: :country, input_html: { tabindex: 5 }
= f.input :permit, collection: Client::PERMITS, as: :radio_buttons, input_html: { tabindex: 7 }
= f.simple_fields_for :contact do |c|
.col-xs-12.col-md-6
= render 'contacts/address_fields', f: c
= render 'contacts/phone_fields', f: c
= render 'contacts/address_fields', f: c, tabindex_start: 7
= render 'contacts/phone_fields', f: c, tabindex_start: 10
fieldset
legend Sprachkenntnisse
......@@ -67,9 +67,8 @@ fieldset
= f.input :other_request
fieldset
legend Wann sind Sie verfügbar?
legend Verfügbarkeit?
= render 'availability/form', f: f
.col-xs-12.col-md-6
fieldset
legend Interne Kriterien
......@@ -79,7 +78,24 @@ fieldset
= f.association :involved_authority, collection: @social_workers
= f.input :competent_authority
= f.input :cost_unit, collection: Client.cost_unit_collection, include_blank: true
- if policy(Client).show_comments?
= f.input :comments
= f.input :additional_comments
fieldset
legend= t_attr(:cost_unit)
= f.input :cost_unit, collection: Client.cost_unit_collection, include_blank: true, label_html: { class: 'sr-only' }
h4 Hinweis
p
'Kosten in der Stadt Zürich: Vermittlung von Freiwilligen ist kostenlos.
br
'Kosten in Gemeinden: Die einmalige Vermittlungspauschale nach einer einmonatigen Probezeit beträgt:
br
'CHF 600 bei TransFair-Unterstützung der Tandems in der AOZ, Stadt Zürich
br
'CHF 800 bei TransFair-Unterstützung der Tandems vor Ort
- if policy(Client).show_comments?
.col-xs-12
hr
.col-xs-12.col-md-6
= f.input :comments, input_html: { class: 'double-height' }
.col-xs-12.col-md-6
= f.input :additional_comments, input_html: { class: 'double-height' }
......@@ -77,7 +77,7 @@ h1.m-b-20= @client.contact.full_name
td= t_attr(:additional_comments)
td= @client.additional_comments
h3 Wann sind Sie verfügbar?
h3 Verfügbarkeit
= render 'availability/show', available: @client
= render 'assignments'
= render 'show_navigation'
- tabindex_start ||= 0
fieldset
legend= t_attr(:address, Contact)
.row
.col-xs-6
= f.input :street, required: true
= f.input :street, required: true, input_html: { tabindex: tabindex_start + 1 }
.col-xs-6
= f.input :extended
.row
.col-xs-4
= f.input :postal_code, required: true
= f.input :postal_code, required: true, input_html: { tabindex: tabindex_start + 2 }
.col-xs-8
= f.input :city, required: true
= f.input :city, required: true, input_html: { tabindex: tabindex_start + 3 }
- tabindex_start ||= 0
fieldset
legend Telefon und Email
.row
.col-xs-12.col-md-6
= f.input :primary_email, as: :email, required: f.object.needs_primary_email?
= f.input :primary_email, as: :email, required: f.object.needs_primary_email?, input_html: { tabindex: tabindex_start + 1 }
.col-xs-12.col-md-6
= f.input :primary_phone, as: :tel, required: f.object.needs_primary_phone?
= f.input :primary_phone, as: :tel, required: f.object.needs_primary_phone?, input_html: { tabindex: tabindex_start + 2 }
- if controller_name == 'clients'
.col-xs-12.col-md-6
= f.input :secondary_phone, as: :tel
= f.input :secondary_phone, as: :tel, input_html: { tabindex: tabindex_start + 3 }
- tabindex_start ||= 0
.row
- if !f.object.client?
.col-xs-12.col-md-6= f.input :first_name, required: true
.col-xs-12.col-md-6= f.input :last_name, required: true, label: t('generic_keys.last_name')
.col-xs-12.col-md-6= f.input :first_name, required: true, input_html: { tabindex: tabindex_start + 1 }
.col-xs-12.col-md-6= f.input :last_name, required: true, label: t('generic_keys.last_name'), input_html: { tabindex: tabindex_start + 2 }
......@@ -51,15 +51,38 @@ wb.add_worksheet(name: 'Veranstaltung') do |sheet|
sheet.add_row(['Teilnehmerliste'], types: :string, style: col_header)
sheet.add_row(['Teilnehmeranzahl', @event.volunteers.count], types: [:string, :integer], style: [col_header, standard_format])
2.times { sheet.add_row }
sheet.add_row(['Name', 'Mailadresse', 'Beginn als FW', 'Adresse', 'Telefon', 'Jahrgang'], types: :string, style: col_header)
row_options = {
types: [
:string, # 00
:string, # 01
:string, # 02
:string, # 03
:string, # 04
:string, # 05
:integer, # 06
],
style: [
standard_format, # 00
standard_format, # 01
standard_format, # 02
date_format, # 03
standard_format, # 04
standard_format, # 05
standard_format, # 06
]
}
sheet.add_row(['Vorname', 'Nachname', 'Mailadresse', 'Beginn als FW', 'Adresse', 'Telefon', 'Jahrgang'], types: :string, style: col_header)
@event.volunteers.map do |volunteer|
[
volunteer.contact&.full_name,
volunteer.contact&.first_name,
volunteer.contact&.last_name,
volunteer.contact&.primary_email,
volunteer.accepted_at.present? ? l(volunteer.accepted_at.to_date) : nil,
volunteer.contact&.full_address,
volunteer.contact&.primary_phone,
volunteer.birth_year&.year,
volunteer.birth_year&.year
]
end.each { |row| sheet.add_row row, row_options }
end
......@@ -46,7 +46,10 @@ wb.add_worksheet(name: t('group_offers', count: 2)) do |sheet|
type = t("offer_type.#{offer.offer_type}") if offer.offer_type?
state = t("offer_state.#{offer.offer_state}") if offer.offer_state?
creator = offer.creator if offer.creator
volunteers = offer.volunteers_with_roles
volunteers = offer.volunteers.map do |volunteer|
role_key = offer.responsible?(volunteer) ? 'responsible' : 'member'
"#{volunteer} (#{I18n.t("activerecord.attributes.group_assignment.#{role_key}")}) #{volunteer.contact.primary_email}"
end.compact
sheet.add_row [
offer.active? ? 'Aktiv' : 'Inaktiv',
......
......@@ -10,7 +10,7 @@
= f.input :profession
h3 Wann sind Sie verfügbar?
h3 Verfügbarkeit?
= render 'availability/form', f: f
.row
......
......@@ -15,7 +15,7 @@
td= t_attr(:profession)
td= @profile.profession
h3 Wann sind Sie verfügbar?
h3 Verfügbarkeit
= render 'availability/show', available: @profile
= form_navigation_btn :edit
......@@ -3,7 +3,7 @@
= f.input_field :kind, value: @reminder_mailing.kind, as: :hidden
.row
.col-xs-12.col-md-4
= render 'email_templates/explain_panel', template_varnames: ReminderMailing::TEMPLATE_VARNAMES
= render 'email_templates/explain_panel', template_varnames: @reminder_mailing.template_varnames.values
.col-xs-12.col-md-8
= render 'email_templates/subject_body_inputs', f: f
......
......@@ -8,7 +8,7 @@
.row
.col-xs-12.col-md-4
= render 'email_templates/explain_panel', template_varnames: SemesterProcessMail::template_varnames[:mail]
= render 'email_templates/explain_panel', template_varnames: SemesterProcessMail.template_varnames.values
.col-xs-12.col-md-8
= render 'email_templates/subject_body_inputs', f: f
......
......@@ -43,47 +43,47 @@
= f.input :salutation,
as: :select,
collection: Volunteer::SALUTATIONS,
include_blank: true
= render 'contacts/user_fields', f: c
include_blank: true, input_html: { tabindex: 1 }
= render 'contacts/user_fields', f: c, tabindex_start: 1
.col-xs-12.col-md-6
= render 'contacts/address_fields', f: c
= render 'contacts/address_fields', f: c, tabindex_start: 3
.col-xs-12.col-md-6
.row
.col-xs-12.col-md-6
= f.input :nationality, as: :country
= f.input :nationality, as: :country, input_html: { tabindex: 9 }
= f.input :birth_year,
as: :select,
collection: Volunteer.year_collection,
include_blank: true
include_blank: true, input_html: { tabindex: 10 }
.col-xs-12.col-md-6
= f.input :additional_nationality, as: :country
= f.input :avatar, as: :file
.row
.col-xs-8
= f.input :profession
= f.input :profession, input_html: { tabindex: 11 }
.col-xs-4
= f.input :working_percent
= f.input :working_percent, input_html: { tabindex: 12 }
.col-xs-6
= f.input :own_kids
= f.input :own_kids, input_html: { tabindex: 13 }
.col-xs-6
= f.input :education
= f.input :education, input_html: { tabindex: 14 }
.col-xs-12
= f.input :motivation
= f.input :motivation, input_html: { tabindex: 15 }
.col-xs-12
= checkbox_toggle_collapse(f, :experience, '#experience-desc')
= checkbox_toggle_collapse(f, :experience, '#experience-desc', tabindex: 16)
.col-xs-12.collapse#experience-desc
= f.input :volunteer_experience_desc
= f.input :volunteer_experience_desc, input_html: { tabindex: 17 }
.col-xs-12.col-md-6
= render 'contacts/phone_fields', f: c
= render 'contacts/phone_fields', f: c, tabindex_start: 6
.col-xs-12.col-md-6
- if current_user.present?
.col-xs-12.col-md-6
fieldset.bank-data
legend Bankdaten für Spesen
= checkbox_toggle_collapse(f, :waive, '.waiver-collapse', check_shows: false)
= f.input :bank, wrapper_html: { class: 'waiver-collapse' }
= f.input :iban, wrapper_html: { class: 'waiver-collapse' }
= checkbox_toggle_collapse(f, :waive, '.waiver-collapse', check_shows: false, tabindex: 18)
= f.input :bank, wrapper_html: { class: 'waiver-collapse' }, input_html: { tabindex: 19 }
= f.input :iban, wrapper_html: { class: 'waiver-collapse' }, input_html: { tabindex: 20 }
.row
.col-xs-12.col-md-6
......@@ -129,5 +129,5 @@ fieldset
- if current_user && policy(volunteer).show_comments?
.col-xs-12.col-md-6
= f.input :comments
= f.input :additional_comments
= f.input :comments, input_html: { class: 'double-height' }
= f.input :additional_comments, input_html: { class: 'double-height' }
......@@ -16,21 +16,10 @@ h1.m-b-20= @volunteer.contact.full_name
.table-responsive
table.table.table-no-border-top
tbody
tr
td= t_attr(:trial_period)
td= t(@volunteer.trial_period)
tr
td= t_attr(:intro_course)
td= t(@volunteer.intro_course)
tr
td= t_attr(:bank_account)
td= t(@volunteer.bank_account)
tr
td= t_attr(:doc_sent)
td= t(@volunteer.doc_sent)
tr
td= t_attr(:evaluation)
td= t(@volunteer.evaluation)
- [:trial_period, :intro_course, :bank_account, :doc_sent, :evaluation].each do |attribute|
tr
td= t_attr(attribute)
td= t(@volunteer[attribute])
h2.small Persönlicher Hintergrund
.table-responsive
......@@ -56,17 +45,14 @@ h2.small Persönlicher Hintergrund
= render 'language_skills/show', speaker: @volunteer
tr
td= t_attr(:profession)
td= @volunteer.profession
tr
td= t_attr(:own_kids)
td= @volunteer.own_kids
tr
td= t_attr(:education)
td= @volunteer.education
tr
td= t_attr(:motivation)
td= @volunteer.motivation
td= t_attr(:working_percent)
td #{@volunteer.working_percent}%
- [:profession, :own_kids, :education, :motivation].each do |attribute|
tr
td= t_attr(attribute)
td= @volunteer[attribute]
tr
td= t_attr(:experience)
td
......@@ -74,15 +60,11 @@ h2.small Persönlicher Hintergrund
dl.dl-horizontal
dt= t(@volunteer.experience)
dd= @volunteer.volunteer_experience_desc
tr
td= t_attr(:expectations)
td= @volunteer.expectations
tr
td= t_attr(:strengths)
td= @volunteer.strengths
tr
td= t_attr(:interests)
td= @volunteer.interests
- [:expectations, :strengths, :interests].each do |attribute|
tr
td= t_attr(attribute)
td= @volunteer[attribute]
- if @volunteer.internal?
tr
td= t_attr(:bank_details)
......@@ -102,12 +84,10 @@ h2.small Persönlicher Hintergrund
- else
= link_to @volunteer.registrar.full_name, profile_url_path(@volunteer.registrar)
- if policy(Volunteer).show_comments?
tr
td= t_attr(:comments)
td= @volunteer.comments
tr
td= t_attr(:additional_comments)
td= @volunteer.additional_comments
- [:comments, :additional_comments].each do |attribute|
tr
td= t_attr(attribute)