diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 269700e83..7eaf4db51 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -49,6 +49,7 @@ #= require invoices #= require cockpit #= require turbolinks +#= require employments app = window.App ||= {} diff --git a/app/assets/javascripts/employments.js.coffee b/app/assets/javascripts/employments.js.coffee new file mode 100644 index 000000000..0ac655871 --- /dev/null +++ b/app/assets/javascripts/employments.js.coffee @@ -0,0 +1,18 @@ +# Copyright (c) 2006-2017, Puzzle ITC GmbH. This file is part of +# PuzzleTime and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/puzzle/puzzletime. + +$ -> + form = $('form[data-needs-confirmation="true"]') + return unless form.length + return if form.data('confirmed') + + if confirm('Möglicherweise ging vergessen die Ferientage pro Jahr einzutragen. Dennoch fortfahren?') + $('') + .attr('type', 'hidden') + .attr('name', 'confirmed') + .val('true') + .appendTo(form) + form.data('confirmed', true) + form.submit() diff --git a/app/controllers/employments_controller.rb b/app/controllers/employments_controller.rb index 6762e81ad..fd34feef5 100644 --- a/app/controllers/employments_controller.rb +++ b/app/controllers/employments_controller.rb @@ -24,6 +24,7 @@ class EmploymentsController < ManageController before_render_form :load_employment_role_levels before_render_form :prefill_from_newest_employment + before_save :check_vacation_days_set before_save :check_percent before_save :check_employment_role_uniqueness @@ -52,6 +53,13 @@ def prefill_from_newest_employment entry.employment_roles_employments = newest.employment_roles_employments.map(&:dup) end + def check_vacation_days_set + return unless entry.needs_vacation_days_confirmation? && !params[:confirmed] + + @needs_confirmation = true + throw :abort + end + def check_percent employment_roles_employments = params[:employment][:employment_roles_employments_attributes] || {} diff --git a/app/models/employment.rb b/app/models/employment.rb index d25fbfdaa..3f4d3dec8 100644 --- a/app/models/employment.rb +++ b/app/models/employment.rb @@ -128,6 +128,17 @@ def date_label(date) date ? I18n.l(date) : 'offen' end + # Defines if confirmation before save is needed when vacation days are left empty + # Applies when latest employment is not older than one year and had vacation days set + def needs_vacation_days_confirmation? + latest = Employment.where(employee_id: employee_id) + .order(start_date: :desc).first + return false unless latest + return false if latest.end_date && latest.end_date < 1.year.ago.to_date + + latest.vacation_days_per_year.present? && vacation_days_per_year.blank? + end + private def vacations_per_period(period, days_per_year) diff --git a/app/views/employments/_form.html.haml b/app/views/employments/_form.html.haml index 395819cf0..39ec7ea2a 100644 --- a/app/views/employments/_form.html.haml +++ b/app/views/employments/_form.html.haml @@ -6,7 +6,7 @@ - @title = ti(:title, model: "#{models_label(false)} von #{h(parent)}") -= crud_form do |f| += crud_form data: { needs_confirmation: @needs_confirmation } do |f| = f.labeled_input_fields :start_date, :end_date = f.labeled_input_field :percent, min: 0, max: 200, step: 2.5 = f.labeled_input_field :vacation_days_per_year, help: 'Feld leer lassen, um den Wert aus den allgemeinen Anstellungsbedingungen zu verwenden.' diff --git a/test/integration/create_employment_test.rb b/test/integration/create_employment_test.rb new file mode 100644 index 000000000..b20b81fd7 --- /dev/null +++ b/test/integration/create_employment_test.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# Copyright (c) 2006-2025, Puzzle ITC GmbH. This file is part of +# PuzzleTime and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/puzzle/puzzletime. + +require 'test_helper' + +class CreateEmploymentTest < ActionDispatch::IntegrationTest + setup :init_view + + test 'new employment' do + page.assert_selector('tbody tr', count: 1) + click_link 'Erstellen' + + page.assert_selector('h1', text: "Anstellung von #{employee.lastname} #{employee.firstname} erstellen") + + fill_in 'employment_start_date', with: Date.current + fill_in 'employment_end_date', with: Date.current + 1 + accept_confirm('Möglicherweise ging vergessen die Ferientage pro Jahr einzutragen. Dennoch fortfahren?') do + click_button 'Speichern' + end + + assert_current_path( + "#{employee_employments_path(employee)}?returning=true", + ignore_query: false + ) + + page.assert_selector('tbody tr', count: 2) + end + + private + + def employee + @employee ||= Fabricate(:employee, management: true) + end + + def init_view + _employment = Fabricate(:employment, employee:, start_date: 2.years.ago.to_date, end_date: 1.day.ago.to_date, percent: 80, vacation_days_per_year: 27) + login_as employee + visit employee_employments_path(employee) + end +end diff --git a/test/models/employment_test.rb b/test/models/employment_test.rb index 737359370..6ae88c743 100644 --- a/test/models/employment_test.rb +++ b/test/models/employment_test.rb @@ -117,6 +117,33 @@ def test_before_create_updates_previous_end_date assert_equal Date.parse('1.6.2013'), before2.end_date end + def test_confirmation_vacation_days_set + employee = Fabricate(:employee) + # Last employment has custom vacation days set + _old = Fabricate(:employment, employee:, start_date: 2.years.ago.to_date, end_date: nil, percent: 80, vacation_days_per_year: 27) + new = Employment.new(employee:, start_date: 1.day.ago.to_date, end_date: nil, percent: 80, vacation_days_per_year: nil) + + assert_predicate new, :needs_vacation_days_confirmation? + end + + def test_confirmation_vacation_days_not_set + employee = Fabricate(:employee) + # Last employment has no custom vacation days set + _old = Fabricate(:employment, employee:, start_date: 2.years.ago.to_date, end_date: nil, percent: 80, vacation_days_per_year: nil) + new = Employment.new(employee:, start_date: 1.day.ago.to_date, end_date: nil, percent: 80, vacation_days_per_year: nil) + + assert_not_predicate new, :needs_vacation_days_confirmation? + end + + def test_confirmation_latest_employement_long_ago + employee = Fabricate(:employee) + # Last employment has ended two years ago + _old = Fabricate(:employment, employee:, start_date: 5.years.ago.to_date, end_date: 2.years.ago.to_date, percent: 80, vacation_days_per_year: 27) + new = Employment.new(employee:, start_date: 1.day.ago.to_date, end_date: nil, percent: 80, vacation_days_per_year: nil) + + assert_not_predicate new, :needs_vacation_days_confirmation? + end + def test_vactions assert_equal 20, new_employment('1.1.2000', '31.12.2000').vacations assert_equal 40, new_employment('1.1.2000', '31.12.2001').vacations