[#43819] Basic administration for non working days (excluding danger zone)
https://community.openproject.org/work_packages/43819 WorkingDays as Settingpull/11254/head
parent
16e68736e3
commit
bb107a7223
@ -0,0 +1,47 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2022 the OpenProject GmbH |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See COPYRIGHT and LICENSE files for more details. |
||||
#++ |
||||
|
||||
module Settings |
||||
class WorkingDaysParamsContract < ::ParamsContract |
||||
include RequiresAdminGuard |
||||
|
||||
validate :working_days_are_present |
||||
|
||||
protected |
||||
|
||||
def working_days_are_present |
||||
if working_days.empty? |
||||
errors.add :base, :working_days_are_missing |
||||
end |
||||
end |
||||
|
||||
def working_days |
||||
params[:working_days] |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,25 @@ |
||||
module Admin::Settings |
||||
class WorkingDaysSettingsController < ::Admin::SettingsController |
||||
current_menu_item [:show] do |
||||
:working_days |
||||
end |
||||
|
||||
def default_breadcrumb |
||||
t(:label_working_days) |
||||
end |
||||
|
||||
def show_local_breadcrumb |
||||
true |
||||
end |
||||
|
||||
def settings_params |
||||
settings = super |
||||
settings[:working_days] = settings[:working_days].compact_blank.map(&:to_i).uniq |
||||
settings |
||||
end |
||||
|
||||
def contract_options |
||||
{ params_contract: Settings::WorkingDaysParamsContract } |
||||
end |
||||
end |
||||
end |
@ -1,6 +1,32 @@ |
||||
class WeekDay < ApplicationRecord |
||||
class WeekDay |
||||
DAY_RANGE = Array(1..7) |
||||
|
||||
attr_accessor :day |
||||
|
||||
class << self |
||||
def find_by!(day:) |
||||
raise ActiveRecord::RecordNotFound, "Couldn't find WeekDay with day #{day}" unless day.in?(DAY_RANGE) |
||||
|
||||
new(day:) |
||||
end |
||||
|
||||
def all |
||||
DAY_RANGE.map do |day| |
||||
new(day:) |
||||
end |
||||
end |
||||
end |
||||
|
||||
def initialize(day:) |
||||
self.day = day |
||||
end |
||||
|
||||
def name |
||||
day_names = I18n.t('date.day_names') |
||||
day_names[day % 7] |
||||
end |
||||
|
||||
def working |
||||
Setting.working_days.empty? || day.in?(Setting.working_days) |
||||
end |
||||
end |
||||
|
@ -0,0 +1,55 @@ |
||||
<%#-- copyright |
||||
OpenProject is an open source project management software. |
||||
Copyright (C) 2012-2022 the OpenProject GmbH |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
Copyright (C) 2010-2013 the ChiliProject Team |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License |
||||
as published by the Free Software Foundation; either version 2 |
||||
of the License, or (at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program; if not, write to the Free Software |
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
|
||||
See COPYRIGHT and LICENSE files for more details. |
||||
|
||||
++#%> |
||||
|
||||
<% content_for :header_tags do %> |
||||
<meta name="required_script" content="administration_settings" /> |
||||
<% end %> |
||||
|
||||
<%= toolbar title: t(:label_working_days) %> |
||||
|
||||
<div class="op-toast -warning"> |
||||
<div class="op-toast--content"> |
||||
<p><%= t("working_days.warning") %></p> |
||||
</div> |
||||
</div> |
||||
|
||||
<%= styled_form_tag(admin_settings_working_days_path, method: :patch) do %> |
||||
<section class="form--section"> |
||||
<p> |
||||
<%= t("working_days.info").html_safe %> |
||||
</p> |
||||
<div class="form--field" id="setting_working_days"> |
||||
<%= setting_multiselect :working_days, |
||||
I18n.t('date.day_names').rotate.zip(WeekDay::DAY_RANGE), |
||||
direction: :horizontal, |
||||
label: false %> |
||||
</div> |
||||
</section> |
||||
<%= styled_button_tag t(:button_save), class: '-highlight -with-icon icon-checkmark' %> |
||||
<% end %> |
@ -0,0 +1,21 @@ |
||||
class DropWeekDays < ActiveRecord::Migration[7.0] |
||||
def up |
||||
drop_table :week_days |
||||
end |
||||
|
||||
def down |
||||
create_table :week_days do |t| |
||||
t.integer :day, null: false |
||||
t.boolean :working, null: false, default: true |
||||
|
||||
t.timestamps |
||||
end |
||||
|
||||
execute <<-SQL.squish |
||||
ALTER TABLE week_days |
||||
ADD CONSTRAINT unique_day_number UNIQUE (day); |
||||
ALTER TABLE week_days |
||||
ADD CHECK (day >= 1 AND day <=7); |
||||
SQL |
||||
end |
||||
end |
@ -0,0 +1,48 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2022 the OpenProject GmbH |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See COPYRIGHT and LICENSE files for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
require 'contracts/shared/model_contract_shared_context' |
||||
|
||||
describe Settings::WorkingDaysParamsContract do |
||||
include_context 'ModelContract shared context' |
||||
let(:setting) { Setting } |
||||
let(:current_user) { build_stubbed(:admin) } |
||||
let(:params) { { working_days: [1] } } |
||||
let(:contract) do |
||||
described_class.new(setting, current_user, params:) |
||||
end |
||||
|
||||
it_behaves_like 'contract is valid for active admins and invalid for regular users' |
||||
|
||||
context 'without working days' do |
||||
let(:params) { { working_days: [] } } |
||||
|
||||
include_examples 'contract is invalid', base: :working_days_are_missing |
||||
end |
||||
end |
@ -0,0 +1,86 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2022 the OpenProject GmbH |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See COPYRIGHT and LICENSE files for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe 'Working Days', type: :feature do |
||||
shared_let(:week_days) { week_with_saturday_and_sunday_as_weekend } |
||||
shared_let(:admin) { create :admin } |
||||
|
||||
before do |
||||
login_as(admin) |
||||
visit admin_settings_working_days_path |
||||
end |
||||
|
||||
it 'contains all defined days from the settings' do |
||||
WeekDay.all.each do |day| |
||||
expect(page).to have_selector('label', text: day.name) |
||||
if day.working |
||||
expect(page).to have_checked_field day.name |
||||
end |
||||
end |
||||
end |
||||
|
||||
it 'updates the values and saves the settings' do |
||||
expect(Setting.working_days).to eq([1, 2, 3, 4, 5]) |
||||
uncheck 'Monday' |
||||
uncheck 'Friday' |
||||
click_on 'Save' |
||||
|
||||
expect(page).to have_selector('.flash.notice', text: 'Successful update.') |
||||
expect(page).to have_unchecked_field 'Monday' |
||||
expect(page).to have_unchecked_field 'Friday' |
||||
expect(page).to have_unchecked_field 'Saturday' |
||||
expect(page).to have_unchecked_field 'Sunday' |
||||
expect(page).to have_checked_field 'Tuesday' |
||||
expect(page).to have_checked_field 'Wednesday' |
||||
expect(page).to have_checked_field 'Thursday' |
||||
expect(Setting.working_days).to eq([2, 3, 4]) |
||||
end |
||||
|
||||
it 'shows error when no working days are set' do |
||||
uncheck 'Monday' |
||||
uncheck 'Tuesday' |
||||
uncheck 'Wednesday' |
||||
uncheck 'Thursday' |
||||
uncheck 'Friday' |
||||
|
||||
click_on 'Save' |
||||
|
||||
expect(page).to have_selector('.flash.error', text: 'At least one working day needs to be specified.') |
||||
# Restore the checkboxes to their valid state |
||||
expect(page).to have_checked_field 'Monday' |
||||
expect(page).to have_checked_field 'Tuesday' |
||||
expect(page).to have_checked_field 'Wednesday' |
||||
expect(page).to have_checked_field 'Thursday' |
||||
expect(page).to have_checked_field 'Friday' |
||||
expect(page).to have_unchecked_field 'Saturday' |
||||
expect(page).to have_unchecked_field 'Sunday' |
||||
expect(Setting.working_days).to eq([1, 2, 3, 4, 5]) |
||||
end |
||||
end |
@ -0,0 +1,78 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2022 the OpenProject GmbH |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See COPYRIGHT and LICENSE files for more details. |
||||
#++ |
||||
|
||||
def week_with_saturday_and_sunday_as_weekend |
||||
Setting.working_days = Array(1..5) |
||||
end |
||||
|
||||
def week_with_all_days_working |
||||
Setting.working_days = Array(1..7) |
||||
end |
||||
|
||||
def week_with_no_working_days |
||||
# This a hack to make all days non-working, |
||||
# because we don't allow that by definition |
||||
Setting.working_days = [false] |
||||
end |
||||
|
||||
def set_non_working_week_days(*days) |
||||
week_days = get_week_days(*days) |
||||
Setting.working_days -= week_days |
||||
end |
||||
|
||||
def set_working_week_days(*days) |
||||
week_days = get_week_days(*days) |
||||
Setting.working_days += week_days |
||||
end |
||||
|
||||
def set_week_days(*days, working: true) |
||||
if working |
||||
set_working_week_days(*days) |
||||
else |
||||
set_non_working_week_days(*days) |
||||
end |
||||
end |
||||
|
||||
def reset_working_week_days(*days) |
||||
week_days = get_week_days(*days) |
||||
Setting.working_days = week_days |
||||
end |
||||
|
||||
def get_week_days(*days) |
||||
days.map do |day| |
||||
%w[xxx monday tuesday wednesday thursday friday saturday sunday].index(day.downcase) |
||||
end |
||||
end |
||||
|
||||
RSpec.configure do |config| |
||||
config.before(:suite) do |
||||
# The test suite assumes the default of all days working. |
||||
# Since the Setting default is with Sat-Sun non-working, we update it before the tests. |
||||
week_with_all_days_working |
||||
end |
||||
end |
Loading…
Reference in new issue