From 0dd110020510bebd7110b73bf313cada3f7758a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Wed, 14 Nov 2018 15:17:20 +0100 Subject: [PATCH] Deprecation notice This repository has been integrated into opf/openproject. See the following PR for more information. https://github.com/opf/openproject/pull/6826 --- .hound.yml | 3 - .rubocop.yml | 270 ------- .travis.yml | 138 ---- Gemfile | 2 - Gemfile.plugins | 11 - README.md | 86 +-- app/assets/javascripts/reporting/reporting.js | 31 - .../stylesheets/reporting/reporting.sass | 29 - app/controllers/cost_reports_controller.rb | 316 -------- app/helpers/reporting_helper.rb | 217 ------ app/models/cost_query.rb | 49 -- app/models/cost_query/cache.rb | 75 -- app/models/cost_query/custom_field_mixin.rb | 158 ---- app/models/cost_query/filter.rb | 48 -- app/models/cost_query/filter/activity_id.rb | 28 - .../cost_query/filter/assigned_to_id.rb | 28 - app/models/cost_query/filter/author_id.rb | 31 - app/models/cost_query/filter/category_id.rb | 33 - .../cost_query/filter/cost_object_id.rb | 31 - app/models/cost_query/filter/cost_type_id.rb | 55 -- app/models/cost_query/filter/created_on.rb | 27 - .../cost_query/filter/custom_field_entries.rb | 53 -- app/models/cost_query/filter/due_date.rb | 28 - .../cost_query/filter/fixed_version_id.rb | 33 - app/models/cost_query/filter/no_filter.rb | 28 - .../cost_query/filter/overridden_costs.rb | 32 - .../cost_query/filter/permission_filter.rb | 57 -- app/models/cost_query/filter/priority_id.rb | 31 - app/models/cost_query/filter/project_id.rb | 48 -- app/models/cost_query/filter/spent_on.rb | 26 - app/models/cost_query/filter/start_date.rb | 28 - app/models/cost_query/filter/status_id.rb | 34 - app/models/cost_query/filter/subject.rb | 28 - app/models/cost_query/filter/tmonth.rb | 30 - app/models/cost_query/filter/tweek.rb | 30 - app/models/cost_query/filter/tyear.rb | 30 - app/models/cost_query/filter/type_id.rb | 31 - app/models/cost_query/filter/updated_on.rb | 27 - app/models/cost_query/filter/user_id.rb | 60 -- .../cost_query/filter/work_package_id.rb | 54 -- app/models/cost_query/group_by.rb | 46 -- app/models/cost_query/group_by/activity_id.rb | 24 - .../cost_query/group_by/assigned_to_id.rb | 27 - app/models/cost_query/group_by/author_id.rb | 27 - app/models/cost_query/group_by/base.rb | 24 - app/models/cost_query/group_by/category_id.rb | 27 - .../cost_query/group_by/cost_object_id.rb | 27 - .../cost_query/group_by/cost_type_id.rb | 25 - .../group_by/custom_field_entries.rb | 24 - .../cost_query/group_by/fixed_version_id.rb | 27 - app/models/cost_query/group_by/priority_id.rb | 27 - app/models/cost_query/group_by/project_id.rb | 25 - .../cost_query/group_by/ruby_aggregation.rb | 32 - .../cost_query/group_by/singleton_value.rb | 22 - app/models/cost_query/group_by/spent_on.rb | 24 - .../cost_query/group_by/sql_aggregation.rb | 30 - app/models/cost_query/group_by/status_id.rb | 27 - app/models/cost_query/group_by/tmonth.rb | 25 - app/models/cost_query/group_by/tweek.rb | 25 - app/models/cost_query/group_by/tyear.rb | 25 - app/models/cost_query/group_by/type_id.rb | 27 - app/models/cost_query/group_by/user_id.rb | 25 - app/models/cost_query/group_by/week.rb | 24 - .../cost_query/group_by/work_package_id.rb | 25 - app/models/cost_query/operator.rb | 61 -- app/models/cost_query/query_utils.rb | 52 -- app/models/cost_query/result.rb | 57 -- app/models/cost_query/sql_statement.rb | 119 ---- app/models/cost_query/table.rb | 20 - app/models/entry.rb | 108 --- .../cost_reports/_report_category.html.erb | 29 - app/views/cost_reports/_report_list.html.erb | 30 - .../cost_reports/_reporting_header.html.erb | 26 - app/views/cost_reports/index.html.erb | 50 -- config/locales/crowdin/ar.yml | 49 -- config/locales/crowdin/da.yml | 49 -- config/locales/crowdin/de.yml | 49 -- config/locales/crowdin/es-ES.yml | 49 -- config/locales/crowdin/fi.yml | 49 -- config/locales/crowdin/fr.yml | 49 -- config/locales/crowdin/he.yml | 49 -- config/locales/crowdin/hr.yml | 49 -- config/locales/crowdin/hu.yml | 49 -- config/locales/crowdin/id.yml | 49 -- config/locales/crowdin/it.yml | 49 -- config/locales/crowdin/ja.yml | 49 -- config/locales/crowdin/ko.yml | 49 -- config/locales/crowdin/lt.yml | 49 -- config/locales/crowdin/nl.yml | 49 -- config/locales/crowdin/pl.yml | 49 -- config/locales/crowdin/pt-BR.yml | 49 -- config/locales/crowdin/pt-PT.yml | 49 -- config/locales/crowdin/ro.yml | 49 -- config/locales/crowdin/ru.yml | 49 -- config/locales/crowdin/sv-SE.yml | 49 -- config/locales/crowdin/tr.yml | 49 -- config/locales/crowdin/zh-CN.yml | 49 -- config/locales/crowdin/zh-TW.yml | 49 -- config/locales/en.yml | 77 -- config/routes.rb | 48 -- ...to_v710_aggregated_reporting_migrations.rb | 54 -- doc/CHANGELOG.md | 72 -- doc/COPYRIGHT.md | 18 - doc/COPYRIGHT_short.md | 16 - doc/GPL.txt | 674 ------------------ .../step_definitions/disabled_scenarios.rb | 21 - lib/open_project/reporting.rb | 24 - lib/open_project/reporting/default_data.rb | 32 - lib/open_project/reporting/engine.rb | 111 --- lib/open_project/reporting/hooks.rb | 21 - lib/open_project/reporting/patches.rb | 21 - .../patches/costlog_controller_patch.rb | 85 --- .../patches/custom_fields_controller_patch.rb | 84 --- .../open_project/configuration_patch.rb | 47 -- .../reporting/patches/role_seeder_patch.rb | 32 - .../reporting/patches/setting_seeder_patch.rb | 36 - .../patches/timelog_controller_patch.rb | 85 --- lib/open_project/reporting/version.rb | 24 - lib/openproject-reporting.rb | 20 - lib/widget/cost_types.rb | 46 -- lib/widget/entry_table.rb | 165 ----- lib/widget/settings_patch.rb | 39 - openproject-reporting.gemspec | 25 - .../cost_reports_controller_spec.rb | 45 -- .../custom_fields_controller_spec.rb | 147 ---- spec/disabled_specs.rb | 27 - spec/factories/cost_query_factory.rb | 32 - spec/features/calculations_spec.rb | 49 -- spec/features/custom_fields_spec.rb | 231 ------ spec/features/filter_spec.rb | 35 - spec/features/grouping_spec.rb | 116 --- spec/features/me_value_spec.rb | 93 --- spec/features/menu_spec.rb | 120 ---- spec/features/my_time_spec.rb | 40 -- spec/features/permissions_spec.rb | 145 ---- spec/features/project_context_spec.rb | 24 - spec/features/saving_spec.rb | 57 -- spec/features/subproject_spec.rb | 28 - .../support/pages/cost_report_page.rb | 86 --- spec/features/update_cost_report_spec.rb | 60 -- spec/lib/open_project/configuration_spec.rb | 47 -- .../reporting/default_data_spec.rb | 58 -- spec/models/cost_query/cache_spec.rb | 124 ---- spec/models/cost_query/chaining_spec.rb | 322 --------- spec/models/cost_query/cost_query_spec.rb | 106 --- spec/models/cost_query/filter_spec.rb | 447 ------------ spec/models/cost_query/group_by_spec.rb | 294 -------- spec/models/cost_query/integration_spec.rb | 105 --- spec/models/cost_query/operator_spec.rb | 270 ------- spec/models/cost_query/result_spec.rb | 147 ---- spec/models/cost_query/validation_spec.rb | 77 -- spec/models/cost_query/walker_spec.rb | 59 -- spec/requests/custom_field_cache_spec.rb | 124 ---- spec/spec_helper.rb | 23 - spec/support/configuration_helper.rb | 31 - spec/support/custom_field_filter.rb | 34 - spec/support/plugin_spec_helper.rb | 30 - spec/support/query_helper.rb | 36 - 158 files changed, 4 insertions(+), 10265 deletions(-) delete mode 100644 .hound.yml delete mode 100644 .rubocop.yml delete mode 100644 .travis.yml delete mode 100644 Gemfile delete mode 100644 Gemfile.plugins delete mode 100644 app/assets/javascripts/reporting/reporting.js delete mode 100644 app/assets/stylesheets/reporting/reporting.sass delete mode 100644 app/controllers/cost_reports_controller.rb delete mode 100644 app/helpers/reporting_helper.rb delete mode 100644 app/models/cost_query.rb delete mode 100644 app/models/cost_query/cache.rb delete mode 100644 app/models/cost_query/custom_field_mixin.rb delete mode 100644 app/models/cost_query/filter.rb delete mode 100644 app/models/cost_query/filter/activity_id.rb delete mode 100644 app/models/cost_query/filter/assigned_to_id.rb delete mode 100644 app/models/cost_query/filter/author_id.rb delete mode 100644 app/models/cost_query/filter/category_id.rb delete mode 100644 app/models/cost_query/filter/cost_object_id.rb delete mode 100644 app/models/cost_query/filter/cost_type_id.rb delete mode 100644 app/models/cost_query/filter/created_on.rb delete mode 100644 app/models/cost_query/filter/custom_field_entries.rb delete mode 100644 app/models/cost_query/filter/due_date.rb delete mode 100644 app/models/cost_query/filter/fixed_version_id.rb delete mode 100644 app/models/cost_query/filter/no_filter.rb delete mode 100644 app/models/cost_query/filter/overridden_costs.rb delete mode 100644 app/models/cost_query/filter/permission_filter.rb delete mode 100644 app/models/cost_query/filter/priority_id.rb delete mode 100644 app/models/cost_query/filter/project_id.rb delete mode 100644 app/models/cost_query/filter/spent_on.rb delete mode 100644 app/models/cost_query/filter/start_date.rb delete mode 100644 app/models/cost_query/filter/status_id.rb delete mode 100644 app/models/cost_query/filter/subject.rb delete mode 100644 app/models/cost_query/filter/tmonth.rb delete mode 100644 app/models/cost_query/filter/tweek.rb delete mode 100644 app/models/cost_query/filter/tyear.rb delete mode 100644 app/models/cost_query/filter/type_id.rb delete mode 100644 app/models/cost_query/filter/updated_on.rb delete mode 100644 app/models/cost_query/filter/user_id.rb delete mode 100644 app/models/cost_query/filter/work_package_id.rb delete mode 100644 app/models/cost_query/group_by.rb delete mode 100644 app/models/cost_query/group_by/activity_id.rb delete mode 100644 app/models/cost_query/group_by/assigned_to_id.rb delete mode 100644 app/models/cost_query/group_by/author_id.rb delete mode 100644 app/models/cost_query/group_by/base.rb delete mode 100644 app/models/cost_query/group_by/category_id.rb delete mode 100644 app/models/cost_query/group_by/cost_object_id.rb delete mode 100644 app/models/cost_query/group_by/cost_type_id.rb delete mode 100644 app/models/cost_query/group_by/custom_field_entries.rb delete mode 100644 app/models/cost_query/group_by/fixed_version_id.rb delete mode 100644 app/models/cost_query/group_by/priority_id.rb delete mode 100644 app/models/cost_query/group_by/project_id.rb delete mode 100644 app/models/cost_query/group_by/ruby_aggregation.rb delete mode 100644 app/models/cost_query/group_by/singleton_value.rb delete mode 100644 app/models/cost_query/group_by/spent_on.rb delete mode 100644 app/models/cost_query/group_by/sql_aggregation.rb delete mode 100644 app/models/cost_query/group_by/status_id.rb delete mode 100644 app/models/cost_query/group_by/tmonth.rb delete mode 100644 app/models/cost_query/group_by/tweek.rb delete mode 100644 app/models/cost_query/group_by/tyear.rb delete mode 100644 app/models/cost_query/group_by/type_id.rb delete mode 100644 app/models/cost_query/group_by/user_id.rb delete mode 100644 app/models/cost_query/group_by/week.rb delete mode 100644 app/models/cost_query/group_by/work_package_id.rb delete mode 100644 app/models/cost_query/operator.rb delete mode 100644 app/models/cost_query/query_utils.rb delete mode 100644 app/models/cost_query/result.rb delete mode 100644 app/models/cost_query/sql_statement.rb delete mode 100644 app/models/cost_query/table.rb delete mode 100644 app/models/entry.rb delete mode 100644 app/views/cost_reports/_report_category.html.erb delete mode 100644 app/views/cost_reports/_report_list.html.erb delete mode 100644 app/views/cost_reports/_reporting_header.html.erb delete mode 100644 app/views/cost_reports/index.html.erb delete mode 100644 config/locales/crowdin/ar.yml delete mode 100644 config/locales/crowdin/da.yml delete mode 100644 config/locales/crowdin/de.yml delete mode 100644 config/locales/crowdin/es-ES.yml delete mode 100644 config/locales/crowdin/fi.yml delete mode 100644 config/locales/crowdin/fr.yml delete mode 100644 config/locales/crowdin/he.yml delete mode 100644 config/locales/crowdin/hr.yml delete mode 100644 config/locales/crowdin/hu.yml delete mode 100644 config/locales/crowdin/id.yml delete mode 100644 config/locales/crowdin/it.yml delete mode 100644 config/locales/crowdin/ja.yml delete mode 100644 config/locales/crowdin/ko.yml delete mode 100644 config/locales/crowdin/lt.yml delete mode 100644 config/locales/crowdin/nl.yml delete mode 100644 config/locales/crowdin/pl.yml delete mode 100644 config/locales/crowdin/pt-BR.yml delete mode 100644 config/locales/crowdin/pt-PT.yml delete mode 100644 config/locales/crowdin/ro.yml delete mode 100644 config/locales/crowdin/ru.yml delete mode 100644 config/locales/crowdin/sv-SE.yml delete mode 100644 config/locales/crowdin/tr.yml delete mode 100644 config/locales/crowdin/zh-CN.yml delete mode 100644 config/locales/crowdin/zh-TW.yml delete mode 100644 config/locales/en.yml delete mode 100644 config/routes.rb delete mode 100644 db/migrate/20180323130704_to_v710_aggregated_reporting_migrations.rb delete mode 100644 doc/CHANGELOG.md delete mode 100644 doc/COPYRIGHT.md delete mode 100644 doc/COPYRIGHT_short.md delete mode 100644 doc/GPL.txt delete mode 100644 features/step_definitions/disabled_scenarios.rb delete mode 100644 lib/open_project/reporting.rb delete mode 100644 lib/open_project/reporting/default_data.rb delete mode 100644 lib/open_project/reporting/engine.rb delete mode 100644 lib/open_project/reporting/hooks.rb delete mode 100644 lib/open_project/reporting/patches.rb delete mode 100644 lib/open_project/reporting/patches/costlog_controller_patch.rb delete mode 100644 lib/open_project/reporting/patches/custom_fields_controller_patch.rb delete mode 100644 lib/open_project/reporting/patches/open_project/configuration_patch.rb delete mode 100644 lib/open_project/reporting/patches/role_seeder_patch.rb delete mode 100644 lib/open_project/reporting/patches/setting_seeder_patch.rb delete mode 100644 lib/open_project/reporting/patches/timelog_controller_patch.rb delete mode 100644 lib/open_project/reporting/version.rb delete mode 100644 lib/openproject-reporting.rb delete mode 100644 lib/widget/cost_types.rb delete mode 100644 lib/widget/entry_table.rb delete mode 100644 lib/widget/settings_patch.rb delete mode 100644 openproject-reporting.gemspec delete mode 100644 spec/controllers/cost_reports_controller_spec.rb delete mode 100644 spec/controllers/custom_fields_controller_spec.rb delete mode 100644 spec/disabled_specs.rb delete mode 100644 spec/factories/cost_query_factory.rb delete mode 100644 spec/features/calculations_spec.rb delete mode 100644 spec/features/custom_fields_spec.rb delete mode 100644 spec/features/filter_spec.rb delete mode 100644 spec/features/grouping_spec.rb delete mode 100644 spec/features/me_value_spec.rb delete mode 100644 spec/features/menu_spec.rb delete mode 100644 spec/features/my_time_spec.rb delete mode 100644 spec/features/permissions_spec.rb delete mode 100644 spec/features/project_context_spec.rb delete mode 100644 spec/features/saving_spec.rb delete mode 100644 spec/features/subproject_spec.rb delete mode 100644 spec/features/support/pages/cost_report_page.rb delete mode 100644 spec/features/update_cost_report_spec.rb delete mode 100644 spec/lib/open_project/configuration_spec.rb delete mode 100644 spec/lib/open_project/reporting/default_data_spec.rb delete mode 100644 spec/models/cost_query/cache_spec.rb delete mode 100644 spec/models/cost_query/chaining_spec.rb delete mode 100644 spec/models/cost_query/cost_query_spec.rb delete mode 100644 spec/models/cost_query/filter_spec.rb delete mode 100644 spec/models/cost_query/group_by_spec.rb delete mode 100644 spec/models/cost_query/integration_spec.rb delete mode 100644 spec/models/cost_query/operator_spec.rb delete mode 100644 spec/models/cost_query/result_spec.rb delete mode 100644 spec/models/cost_query/validation_spec.rb delete mode 100644 spec/models/cost_query/walker_spec.rb delete mode 100644 spec/requests/custom_field_cache_spec.rb delete mode 100644 spec/spec_helper.rb delete mode 100644 spec/support/configuration_helper.rb delete mode 100644 spec/support/custom_field_filter.rb delete mode 100644 spec/support/plugin_spec_helper.rb delete mode 100644 spec/support/query_helper.rb diff --git a/.hound.yml b/.hound.yml deleted file mode 100644 index c67bfeca..00000000 --- a/.hound.yml +++ /dev/null @@ -1,3 +0,0 @@ -ruby: - enabled: true - config_file: .rubocop.yml \ No newline at end of file diff --git a/.rubocop.yml b/.rubocop.yml deleted file mode 100644 index a5262e35..00000000 --- a/.rubocop.yml +++ /dev/null @@ -1,270 +0,0 @@ -AllCops: - TargetRubyVersion: 2.2 - Exclude: - - db/schema.rb - -AccessorMethodName: - Enabled: false - -ActionFilter: - Enabled: false - -Alias: - Enabled: false - -AndOr: - Enabled: false - -ArrayJoin: - Enabled: false - -AsciiComments: - Enabled: false - -AsciiIdentifiers: - Enabled: false - -Attr: - Enabled: false - -BlockLength: - Enabled: false - -BlockNesting: - Enabled: false - -CaseEquality: - Enabled: false - -CharacterLiteral: - Enabled: false - -ClassAndModuleChildren: - Enabled: false - -ClassLength: - Enabled: false - -ClassVars: - Enabled: false - -CollectionMethods: - PreferredMethods: - find: detect - reduce: inject - collect: map - find_all: select - -ColonMethodCall: - Enabled: false - -CommentAnnotation: - Enabled: false - -CyclomaticComplexity: - Enabled: false - -Delegate: - Enabled: false - -PreferredHashMethods: - Enabled: false - -Documentation: - Enabled: false - -DotPosition: - EnforcedStyle: leading - -DoubleNegation: - Enabled: false - -EachWithObject: - Enabled: false - -EmptyLiteral: - Enabled: false - -Encoding: - Enabled: false - -EvenOdd: - Enabled: false - -FileName: - Enabled: false - -FlipFlop: - Enabled: false - -FormatString: - Enabled: false - -GlobalVars: - Enabled: false - -GuardClause: - Enabled: false - -IfUnlessModifier: - Enabled: false - -IfWithSemicolon: - Enabled: false - -InlineComment: - Enabled: false - -Lambda: - Enabled: false - -LambdaCall: - Enabled: false - -LineEndConcatenation: - Enabled: false - -LineLength: - Max: 130 - -MethodLength: - Enabled: false - -ModuleFunction: - Enabled: false - -NegatedIf: - Enabled: false - -NegatedWhile: - Enabled: false - -Next: - Enabled: false - -NilComparison: - Enabled: false - -Not: - Enabled: false - -NumericLiterals: - Enabled: false - -OneLineConditional: - Enabled: false - -BinaryOperatorParameterName: - Enabled: false - -ParameterLists: - Enabled: false - -PercentLiteralDelimiters: - Enabled: false - -PerlBackrefs: - Enabled: false - -PredicateName: - NamePrefixBlacklist: - - is_ - -Proc: - Enabled: false - -RaiseArgs: - Enabled: false - -RegexpLiteral: - Enabled: false - -SelfAssignment: - Enabled: false - -SingleLineBlockParams: - Enabled: false - -SingleLineMethods: - Enabled: false - -SignalException: - Enabled: false - -SpecialGlobalVars: - Enabled: false - -# Forcing single quotes doesn't give any reasonable advantages. To the contrary: -# it forces you to change the quotes every time you want to add interpolation, -# newlines or other escape sequences (\n), or quotes (') to a string. Rubbish. -# Don't even think about performance. That never was a valid argument to begin with. -# -# For the record: using single quotes does NOT have any performance advantages. -# Even if it did, this would be a silly argument. -# -# Ideally we would just use double quotes everywhere but since that would result -# in innumerable rubocop offenses we will just disable this. Quote away. -StringLiterals: - Enabled: false - -VariableInterpolation: - Enabled: false - -TrivialAccessors: - Enabled: false - -VariableInterpolation: - Enabled: false - -WhenThen: - Enabled: false - -WhileUntilModifier: - Enabled: false - -WordArray: - Enabled: false - -# Lint - -AmbiguousOperator: - Enabled: false - -AmbiguousRegexpLiteral: - Enabled: false - -AssignmentInCondition: - Enabled: false - -ConditionPosition: - Enabled: false - -DeprecatedClassMethods: - Enabled: false - -ElseLayout: - Enabled: false - -HandleExceptions: - Enabled: false - -LiteralInCondition: - Enabled: false - -LiteralInInterpolation: - Enabled: false - -Loop: - Enabled: false - -ParenthesesAsGroupedExpression: - Enabled: false - -RequireParentheses: - Enabled: false - -UnderscorePrefixedVariableName: - Enabled: false - -Void: - Enabled: false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f877d60b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,138 +0,0 @@ -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# 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-2018 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 doc/COPYRIGHT.rdoc for more details. -#++ - - -################################### -# -# This file was generated by -# openproject-devkit. -# -# Do not modify this file directly! -# -################################### - -language: ruby - -rvm: - - 2.5.1 - -sudo: required -dist: trusty - -cache: - bundler: true - directories: - - frontend/node_modules/foundation-apps - - public/assets - - app/assets/javascripts/bundles - - app/assets/javascripts/locales - -branches: - only: - - master - - dev - - /^(stable|release)\/.*$/ - -env: - global: - - CI=true - - RAILS_ENV=test - - -before_install: - ## Custom plugin instructions follow. - # Move the plugin into a subfolder. The plugin-provided Gemfile.plugins - # must refer to this folder. - - mkdir -p plugins/this - - echo `ls -a | tail -n+3 | grep -v plugins` plugins/this/ | xargs mv - - # Get OpenProject. - # Doing the fetch detour as you cannot clone into the current directory. - - git init - - git remote add openproject https://github.com/opf/openproject.git - - git fetch --depth=1 openproject - - git checkout openproject/$TRAVIS_BRANCH - - # work around https://github.com/travis-ci/travis-ci/issues/8969 - - travis_retry gem update --system - # Don't install 1.16.3 - - gem install bundler -v 1.16.2 - - # Install Node latest LTS - # This should only be necessary when preparing the cache or for npm test runs - # but installing later fails for unknown reasons. - - nvm install --lts - -bundler_args: --binstubs --without development production docker - -stages: - - prepare cache - - test - -jobs: - include: - - stage: prepare cache - name: 'Prepare cache' - script: - - bash script/ci/cache_prepare.sh - - - stage: test - name: 'plugins:units (1/1) - mysql' - script: - - bash script/ci/setup.sh plugins:units mysql - - bash script/ci/runner.sh plugins:units 1 1 - - stage: test - name: 'plugins:units (1/1) - postgres' - script: - - bash script/ci/setup.sh plugins:units postgres - - bash script/ci/runner.sh plugins:units 1 1 - - stage: test - name: 'plugins:features (1/1) - mysql' - script: - - bash script/ci/setup.sh plugins:features mysql - - bash script/ci/runner.sh plugins:features 1 1 - - stage: test - name: 'plugins:features (1/1) - postgres' - script: - - bash script/ci/setup.sh plugins:features postgres - - bash script/ci/runner.sh plugins:features 1 1 - - stage: test - name: 'plugins:cucumber (1/1) - mysql' - script: - - bash script/ci/setup.sh plugins:cucumber mysql - - bash script/ci/runner.sh plugins:cucumber 1 1 - - stage: test - name: 'plugins:cucumber (1/1) - postgres' - script: - - bash script/ci/setup.sh plugins:cucumber postgres - - bash script/ci/runner.sh plugins:cucumber 1 1 - - -addons: - chrome: stable - postgresql: "9.6" diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 3be9c3cd..00000000 --- a/Gemfile +++ /dev/null @@ -1,2 +0,0 @@ -source "https://rubygems.org" -gemspec diff --git a/Gemfile.plugins b/Gemfile.plugins deleted file mode 100644 index af7ee8e9..00000000 --- a/Gemfile.plugins +++ /dev/null @@ -1,11 +0,0 @@ -# Dependencies (need to be called before the actual gem) -group :opf_plugins do - gem "openproject-costs", :git => "https://github.com/finnlabs/openproject-costs.git", :branch => ENV['TRAVIS_BRANCH'] - gem "reporting_engine", :git => "https://github.com/finnlabs/reporting_engine.git", :branch => ENV['TRAVIS_BRANCH'] - - # Used by travis to bundle this plugin with the OpenProject core. - # The tested plugin will be moved to the path `./plugins/this` - # whereas OpenProject will be checked out to `.`. - - gem 'openproject-reporting', path: 'plugins/this' -end diff --git a/README.md b/README.md index 1330d635..5ae095c3 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,6 @@ -OpenProject Reporting Plugin -============================= +# Deprecation notice -The OpenProject Reporting plugin allows to create custom reports for costs associated to projects using the [OpenProject Costs plugin](https://community.openproject.org/projects/costs-plugin). Various attributes including custom fields can be used to filter the data and the results can be grouped by these attributes. +This repository has been integrated into opf/openproject. +See the following PR for more information. -The OpenProject Reporting plugin is built on top of the [ReportingEngine Rails engine](https://community.openproject.org/projects/plugin-reportingengine), providing the base functionality for customized database reports. - -Requirements ------------- - -The OpenProject Reporting plugin requires the [OpenProject Core](https://github.com/opf/openproject/) in -version greater or equal to *3.0.0*. It also requires the [ReportingEngine Rails engine](https://github.com/finnlabs/reporting_engine.git) in version greater or equal to *1.0.0*. Finally, it also requires the [OpenProject Costs plugin](https://github.com/finnlabs/openproject-costs.git). - -Installation ------------- - -Reporting depends on the OpenProject Costs plugin. If you have not installed it yet, you can do so by adding the following line to the `Gemfile.plugins` in your OpenProject installation: - -`gem "openproject-costs", git: "https://github.com/finnlabs/openproject-costs.git", :branch => "stable/5"` - -Furthermore, OpenProject reporting depends on the ReportingEngine which should be installed by adding the following line to your `Gemfile.plugins` in your OpenProject installation folder: - -`gem "reporting_engine", git: "https://github.com/finnlabs/reporting_engine.git", :branch => "dev"` - -Finally, add the following line to your `Gemfile.plugins` in your OpenProject installation folder to use the Reporting plugin: - -`gem "openproject-reporting", git: "https://github.com/finnlabs/openproject-reporting.git", :branch => "stable/5"` - -Afterwards, run: - -`bundle install` - - -Deinstallation --------------- - -Remove the lines - -`gem "reporting_engine", git: "https://github.com/finnlabs/reporting_engine.git", :branch => "dev"` -`gem "openproject-reporting", git: "https://github.com/finnlabs/openproject-reporting.git", :branch => "stable/5"` - -from your `Gemfile.plugins` in your OpenProject installation folder and run: - -`bundle install` - -to uninstall the ReportingEngine and the OpenProject Reporting plugin. - - -Configuration -------------- - -* `cost_reporting_cache_filter_classes: true` - -OpenProject Reporting, when not configured otherwise, optimizes response time by caching the filters and group by options generated for work package custom fields. Only when the custom fields are invalidated, does reporting recreate the elements by information from the database. In some scenarios, such a behavior might not be desirable. Especially, when databases are switched between requests to serve information from another installation, caching will almost always fail as the information is outdated and in some edge cases, filters and group by options are displayed erroneously. In such a setting, it is advisible to deactivate the caching by setting `cost_reporting_cache_filter_classes` to `false` in OpenProject's `config/configuration.yml` - - -Bug Reporting -------------- - -If you find any bugs, you can create a bug ticket at - -https://www.openproject.org/projects/plugin-reporting - - -Development ------------ - -To contribute, you can create pull request on the official repository at -`https://github.com/finnlabs/openproject-reporting` - - -Credits -------- - -Special thanks go to - -* Deutsche Telekom AG (opensource@telekom.de) for project sponsorship - -Licence -------- - -Copyright (C) 2010 - 2015 OpenProject Foundation (OPF) - -This plugin is licensed under the GNU GPL v3. See doc/COPYRIGHT.md and doc/GPL.txt for details. +https://github.com/opf/openproject/pull/6826 diff --git a/app/assets/javascripts/reporting/reporting.js b/app/assets/javascripts/reporting/reporting.js deleted file mode 100644 index c5ad8baf..00000000 --- a/app/assets/javascripts/reporting/reporting.js +++ /dev/null @@ -1,31 +0,0 @@ -//= require jquery-tablesorter - -(function($){ - $(document).ajaxComplete(function() { - // This prevents the tablesorter plugin to check for metadata which is done - // using eval which conflicts with our csp. - // Works because of a check in tablesorter: - // meta = $.metadata ? $header.metadata() : false; - $.metadata = undefined; - - // Override the default texts to enable translations - $.tablesorter.language = { - sortAsc : I18n.t('js.sort.sorted_asc'), - sortDesc : I18n.t('js.sort.sorted_dsc'), - sortNone : I18n.t('js.sort.sorted_no'), - sortDisabled : I18n.t('js.sort.sorting_disabled'), - nextAsc : I18n.t('js.sort.activate_asc'), - nextDesc : I18n.t('js.sort.activate_dsc'), - nextNone : I18n.t('js.sort.activate_no') - }; - - $('#sortable-table') - .not('.tablesorter') - .tablesorter({ - sortList: [[0, 0]], - textExtraction: function(node, table, cellIndex) { - return $(node).attr('raw-data'); - } - }); - }); -})(jQuery); diff --git a/app/assets/stylesheets/reporting/reporting.sass b/app/assets/stylesheets/reporting/reporting.sass deleted file mode 100644 index 1e5e76ee..00000000 --- a/app/assets/stylesheets/reporting/reporting.sass +++ /dev/null @@ -1,29 +0,0 @@ -@import "fonts/openproject_icon_definitions" - -@mixin sort-icons - font-family: "openproject-icon-font" !important - font-weight: normal !important - speak: none - margin-left: 5px - font-size: 1.2em - line-height: 1 - vertical-align: text-bottom - -.tablesorter-header - cursor: pointer - -.tablesorter-headerDesc .generic-table--sort-header span - &:after - @include sort-icons - @include icon-mixin-sort-descending - -.tablesorter-headerAsc .generic-table--sort-header span - &:after - @include sort-icons - @include icon-mixin-sort-ascending - -#result-table .generic-table--results-container tfoot - td - width: 150px - .generic-table--footer-outer - width: inherit \ No newline at end of file diff --git a/app/controllers/cost_reports_controller.rb b/app/controllers/cost_reports_controller.rb deleted file mode 100644 index 2e481f92..00000000 --- a/app/controllers/cost_reports_controller.rb +++ /dev/null @@ -1,316 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostReportsController < ApplicationController - module QueryPreperation - ## - # Make sure to add cost type filter after the - # query filters have been reset by .prepare_query - # from the Report::Controller. - def prepare_query - query = super - - set_cost_type if @unit_id.present? - - query - end - end - - rescue_from Exception do |exception| - session.delete(CostQuery.name.underscore.to_sym) - raise exception - end - - rescue_from ActiveRecord::RecordNotFound do |_exception| - render_404 - end - - Widget::Base.dont_cache! - - before_action :check_cache - before_action :load_all - before_action :find_optional_project - before_action :find_optional_user - - include Report::Controller - include Concerns::Layout - prepend QueryPreperation - - before_action :set_cost_types # has to be set AFTER the Report::Controller filters run - - verify method: :delete, only: %w[destroy] - verify method: :post, only: %w[create, update, rename] - - helper_method :cost_types - helper_method :cost_type - helper_method :unit_id - helper_method :public_queries - helper_method :private_queries - - attr_accessor :cost_types, :unit_id, :cost_type - - # Checks if custom fields have been updated, added or removed since we - # last saw them, to rebuild the filters and group bys. - # Called once per request. - def check_cache - CostQuery::Cache.check - end - - ## - # @Override - # Use respond_to hook, so redmine_export can hook up the excel exporting - def index - super - respond_to do |format| - format.html { - session[report_engine.name.underscore.to_sym].try(:delete, :name) - render action: 'index', layout: layout_non_or_no_menu - } - end unless performed? - end - - current_menu_item :index do |controller| - controller.menu_item_to_highlight_on_index - end - - def menu_item_to_highlight_on_index - @project ? :cost_reports : :cost_reports_global - end - - def drill_down - redirect_to action: :index - end - - ## - # Determines if the request sets a unit type - def set_unit? - params[:unit] - end - - ## - # @Override - # We cannot show a progressbar in Redmine, due to Prototype being less than 1.7 - def no_progress? - true - end - - ## - # Set a default query to cut down initial load time - def default_filter_parameters - { - operators: { spent_on: '>d' }, - values: { spent_on: [30.days.ago.strftime('%Y-%m-%d')] } - }.tap do |hash| - if @project - set_project_filter(hash, @project.id) - end - - if current_user.logged? - set_me_filter(hash) - end - end - end - - ## - # Get the filter params with an optional project context - def filter_params - filters = super - update_project_context!(filters) - - filters - end - - ## - # Clear the query if the project context changed - def update_project_context!(filters) - - # Only in project context - return unless @project - - # Only if the project context changed - context = filters[:project_context] - - # Context is same, don't set project (allow override) - return if context == @project.id - - # Reset context if project missing - if context.nil? - filters[:project_context] = @project.id - return - end - - # Update the project context and project_id filter - set_project_filter(filters, @project.id) - end - - def set_project_filter(filters, project_id) - filters[:project_context] = project_id - filters[:operators].merge! project_id: '=' - filters[:values].merge! project_id: [project_id] - end - - def set_me_filter(filters) - filters[:operators].merge! user_id: '=' - filters[:values].merge! user_id: [CostQuery::Filter::UserId.me_value] - end - - ## - # Set a default query to cut down initial load time - def default_group_parameters - { columns: [:week], rows: [] }.tap do |h| - if @project - h[:rows] << :work_package_id - else - h[:rows] << :project_id - end - end - end - - ## - # Determine active cost types, the currently selected unit and corresponding cost type - def set_cost_types - set_active_cost_types - set_unit - set_cost_type - end - - # Determine the currently active unit from the parameters or session - # sets the @unit_id -> this is used in the index for determining the active unit tab - def set_unit - @unit_id = if set_unit? - params[:unit].to_i - elsif @query.present? - cost_type_filter = @query.filters.detect { |f| f.is_a?(CostQuery::Filter::CostTypeId) } - - cost_type_filter.values.first.to_i if cost_type_filter - end - - @unit_id = -1 unless @cost_types.include? @unit_id - end - - # Determine the active cost type, if it is not labor or money, and add a hidden filter to the query - # sets the @cost_type -> this is used to select the proper units for display - def set_cost_type - return unless @query - - @query.filter :cost_type_id, operator: '=', value: @unit_id.to_s, display: false - @cost_type = CostType.find(@unit_id) if @unit_id > 0 - end - - # set the @cost_types -> this is used to determine which tabs to display - def set_active_cost_types - unless session[:report] && (@cost_types = session[:report][:filters][:values][:cost_type_id].try(:collect, &:to_i)) - relevant_cost_types = CostType.select(:id).order('id ASC').select do |t| - t.cost_entries.count > 0 - end.collect(&:id) - @cost_types = [-1, 0, *relevant_cost_types] - end - end - - def load_all - CostQuery::GroupBy.all - CostQuery::Filter.all - end - - # @Override - def determine_engine - @report_engine = CostQuery - @title = "label_#{@report_engine.name.underscore}" - end - - # N.B.: Users with save_cost_reports permission implicitly have - # save_private_cost_reports permission as well - # - # @Override - def allowed_to?(action, report, user = User.current) - # admins may do everything - return true if user.admin? - - # If this report does belong to a project but not to the current project, we - # should not do anything with it. It fact, this should never happen. - return false if report.project.present? && report.project != @project - - # If report does not belong to a project, it is ok to look for the - # permission in any project. Otherwise, the user should have the permission - # in this project. - if report.project.present? - options = {} - else - options = { global: true } - end - - case action - when :create - user.allowed_to?(:save_cost_reports, @project, options) or - user.allowed_to?(:save_private_cost_reports, @project, options) - - when :save, :destroy, :rename - if report.is_public? - user.allowed_to?(:save_cost_reports, @project, options) - else - user.allowed_to?(:save_cost_reports, @project, options) or - user.allowed_to?(:save_private_cost_reports, @project, options) - end - - when :save_as_public - user.allowed_to?(:save_cost_reports, @project, options) - - else - false - end - end - - def public_queries - if @project - CostQuery.where(['is_public = ? AND (project_id IS NULL OR project_id = ?)', true, @project]) - .order('name ASC') - else - CostQuery.where(['is_public = ? AND project_id IS NULL', true]) - .order('name ASC') - end - end - - def private_queries - if @project - CostQuery.where(['user_id = ? AND is_public = ? AND (project_id IS NULL OR project_id = ?)', - current_user, - false, - @project]) - .order('name ASC') - else - CostQuery.where(['user_id = ? AND is_public = ? AND project_id IS NULL', current_user, false]) - .order('name ASC') - end - end - - def display_report_list - report_type = params[:report_type] || :public - render partial: 'report_list', locals: { report_type: report_type }, layout: !request.xhr? - end - - private - - def find_optional_user - @current_user = User.current || User.anonymous - end - - def default_breadcrumb - l(:cost_reports_title) - end -end diff --git a/app/helpers/reporting_helper.rb b/app/helpers/reporting_helper.rb deleted file mode 100644 index 00f1288d..00000000 --- a/app/helpers/reporting_helper.rb +++ /dev/null @@ -1,217 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require 'digest/md5' -require 'date' - -module ReportingHelper - # ======================= SHARED CODE START - include ApplicationHelper - include WorkPackagesHelper - - def with_project(project) - project = Project.find(project) unless project.is_a? Project - project_was, @project = @project, project - yield - @project = project_was - end - - def mapped(value, klass, default) - id = value.to_i - return default if id < 0 - klass.find(id).name - end - - def label_for(field) - name = field.to_s - if name.starts_with?('label') - return I18n.t(field) - end - name = name.camelcase - if CostQuery::Filter.const_defined? name - CostQuery::Filter.const_get(name).label - elsif - CostQuery::GroupBy.const_defined? name - CostQuery::GroupBy.const_get(name).label - else - # note that using WorkPackage.human_attribute_name relies on the attribute - # being an work_package attribute or a general attribute for all models whicht might not - # be the case but so far I have only seen the "comments" attribute in reports - WorkPackage.human_attribute_name(field) - end - end - - def debug_fields(result, prefix = ', ') - prefix << result.fields.inspect << ', ' << result.important_fields.inspect << ', ' << result.key.inspect if params[:debug] - end - - def month_name(index) - Date::MONTHNAMES[index].to_s - end - - # ======================= SHARED CODE END - - def show_field(key, value) - @show_row ||= Hash.new { |h, k| h[k] = {} } - @show_row[key][value] ||= field_representation_map(key, value) - end - - def raw_field(key, value) - @raw_row ||= Hash.new { |h, k| h[k] = {} } - @raw_row[key][value] ||= field_sort_map(key, value) - end - - def cost_object_link(cost_object_id) - co = CostObject.find(cost_object_id) - if User.current.allowed_to?(:view_cost_objects, co.project) - link_to_cost_object(co) - else - co.subject - end - end - - def field_representation_map(key, value) - return l(:label_none) if value.blank? - case key.to_sym - when :activity_id then mapped value, Enumeration, "#{l(:caption_material_costs)}" - when :project_id then link_to_project Project.find(value.to_i) - when :user_id, :assigned_to_id, :author_id then link_to_user(User.find_by_id(value.to_i) || DeletedUser.first) - when :tyear, :units then h(value.to_s) - when :tweek then "#{l(:label_week)} ##{h value}" - when :tmonth then month_name(value.to_i) - when :category_id then h(Category.find(value.to_i).name) - when :cost_type_id then mapped value, CostType, l(:caption_labor) - when :cost_object_id then cost_object_link value - when :work_package_id then link_to_work_package(WorkPackage.find(value.to_i)) - when :spent_on then format_date(value.to_date) - when :type_id then h(Type.find(value.to_i).name) - when :week then "#{l(:label_week)} #%s" % value.to_i.modulo(100) - when :priority_id then h(IssuePriority.find(value.to_i).name) - when :fixed_version_id then h(Version.find(value.to_i).name) - when :singleton_value then '' - when :status_id then h(Status.find(value.to_i).name) - else h(value.to_s) - end - end - - def field_sort_map(key, value) - return '' if value.blank? - case key.to_sym - when :work_package_id, :tweek, :tmonth, :week then value.to_i - when :spent_on then value.to_date.mjd - else h(field_representation_map(key, value).gsub(/<\/?[^>]*>/, '')) - end - end - - def show_result(row, unit_id = self.unit_id) - case unit_id - when -1 then l_hours(row.units) - when 0 then row.real_costs ? number_to_currency(row.real_costs) : '-' - else - current_cost_type = @cost_type || CostType.find(unit_id) - pluralize(row.units, current_cost_type.unit, current_cost_type.unit_plural) - end - end - - def set_filter_options(struct, key, value) - struct[:operators][key] = '=' - struct[:values][key] = value.to_s - end - - def available_cost_type_tabs(cost_types) - tabs = cost_types.to_a - tabs.delete 0 # remove money from list - tabs.unshift 0 # add money as first tab - tabs.map { |cost_type_id| [cost_type_id, cost_type_label(cost_type_id)] } - end - - def cost_type_label(cost_type_id, cost_type_inst = nil, _plural = true) - case cost_type_id - when -1 then l(:caption_labor) - when 0 then l(:label_money) - else (cost_type_inst || CostType.find(cost_type_id)).name - end - end - - def link_to_details(result) - return '' # unless result.respond_to? :fields # uncomment to display - session_filter = { operators: session[:report][:filters][:operators].dup, values: session[:report][:filters][:values].dup } - filters = result.fields.inject session_filter do |struct, (key, value)| - key = key.to_sym - case key - when :week - set_filter_options struct, :tweek, value.to_i.modulo(100) - set_filter_options struct, :tyear, value.to_i / 100 - when :month, :year - set_filter_options struct, :"t#{key}", value - when :count, :units, :costs, :display_costs, :sum, :real_costs - else - set_filter_options struct, key, value - end - struct - end - options = { fields: filters[:operators].keys, set_filter: 1, action: :drill_down } - link_to '[+]', filters.merge(options), class: 'drill_down', title: l(:description_drill_down) - end - - ## - # Create the appropriate action for an entry with the type of log to use - def action_for(result, options = {}) - options.merge controller: result.fields['type'] == 'TimeEntry' ? 'timelog' : 'costlog', id: result.fields['id'].to_i - end - - ## - # Create the appropriate action for an entry with the type of log to use - def entry_for(result) - type = result.fields['type'] == 'TimeEntry' ? TimeEntry : CostEntry - type.find(result.fields['id'].to_i) - end - - ## - # For a given row, determine how to render it's contents according to usability and - # localization rules - def show_row(row) - row_text = link_to_details(row) << row.render { |k, v| show_field(k, v) } - row_text.html_safe - end - - def delimit(items, options = {}) - options[:step] ||= 1 - options[:delim] ||= '•' - delimited = [] - items.each_with_index do |item, ix| - if ix != 0 and ix % options[:step] == 0 - delimited << " #{options[:delim]} " + item - else - delimited << item - end - end - delimited - end - - ## - # Finds the Filter-Class for as specific filter name while being careful with the filter_name parameter as it is user input. - def filter_class(filter_name) - klass = CostQuery::Filter.const_get(filter_name.to_s.camelize) - return klass if klass.is_a? Class - nil - rescue NameError - return nil - end -end diff --git a/app/models/cost_query.rb b/app/models/cost_query.rb deleted file mode 100644 index eb663dfd..00000000 --- a/app/models/cost_query.rb +++ /dev/null @@ -1,49 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery < Report - def_delegators :result, :real_costs - - User.before_destroy do |user| - CostQuery.where(user_id: user.id, is_public: false).delete_all - CostQuery.where(['user_id = ?', user.id]).update_all ['user_id = ?', DeletedUser.first.id] - - max_query_id = 0 - while((current_queries = CostQuery.limit(1000) - .where(["id > ?", max_query_id]) - .order("id ASC")).size > 0) do - - current_queries.each do |query| - serialized = query.serialized - - serialized[:filters] = serialized[:filters].map do |name, options| - options[:values].delete(user.id.to_s) if ["UserId", "AuthorId", "AssignedToId"].include?(name) - - options[:values].nil? || options[:values].size > 0 ? - [name, options] : - nil - end.compact - - CostQuery.where(["id = ?", query.id]).update_all ["serialized = ?", YAML::dump(serialized)] - - max_query_id = query.id - end - end - end -end diff --git a/app/models/cost_query/cache.rb b/app/models/cost_query/cache.rb deleted file mode 100644 index d7136038..00000000 --- a/app/models/cost_query/cache.rb +++ /dev/null @@ -1,75 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module CostQuery::Cache - class << self - - def check - reset! if reset_required? - end - - def reset! - update_reset_on - - CostQuery::Filter.reset! - CostQuery::Filter::CustomFieldEntries.reset! - CostQuery::GroupBy.reset! - CostQuery::GroupBy::CustomFieldEntries.reset! - end - - protected - - attr_accessor :latest_custom_field_change, - :custom_field_count - - def invalid? - changed_on = fetch_latest_custom_field_change - field_count = fetch_current_custom_field_count - - latest_custom_field_change != changed_on || - custom_field_count != field_count - end - - def update_reset_on - return if caching_disabled? - - self.latest_custom_field_change = fetch_latest_custom_field_change - self.custom_field_count = fetch_current_custom_field_count - end - - def fetch_latest_custom_field_change - WorkPackageCustomField.maximum(:updated_at) - end - - def fetch_current_custom_field_count - WorkPackageCustomField.count - end - - def caching_disabled? - !OpenProject::Configuration.cost_reporting_cache_filter_classes - end - - def reset_required? - caching_disabled? || invalid? - end - end - - # initialize to 0 to avoid forced cache reset on first request - self.custom_field_count = 0 -end diff --git a/app/models/cost_query/custom_field_mixin.rb b/app/models/cost_query/custom_field_mixin.rb deleted file mode 100644 index ab127611..00000000 --- a/app/models/cost_query/custom_field_mixin.rb +++ /dev/null @@ -1,158 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module CostQuery::CustomFieldMixin - include Report::QueryUtils - - attr_reader :custom_field - SQL_TYPES = { - 'string' => mysql? ? 'char' : 'varchar', - 'list' => mysql? ? 'char' : 'varchar', - 'text' => mysql? ? 'char' : 'text', - 'bool' => mysql? ? 'unsigned' : 'boolean', - 'date' => 'date', - 'int' => 'decimal(60,3)', - 'float' => 'decimal(60,3)' } - - def self.extended(base) - base.inherited_attribute :factory - base.factory = base - super - end - - def all - @all ||= generate_subclasses - end - - def reset! - @all = nil - - remove_subclasses - end - - def generate_subclasses - WorkPackageCustomField.where(field_format: SQL_TYPES.keys).map do |field| - class_name = "CustomField#{field.id}" - parent.send(:remove_const, class_name) if parent.const_defined? class_name - parent.const_set class_name, Class.new(self) - parent.const_get(class_name).prepare(field, class_name) - end - end - - def remove_subclasses - parent.constants.each do |constant| - if constant.to_s.match /^CustomField\d+/ - parent.send(:remove_const, constant) - end - end - end - - def factory? - factory == self - end - - def on_prepare(&block) - return factory.on_prepare unless factory? - @on_prepare = block if block - @on_prepare ||= proc {} - @on_prepare - end - - def table_name - @class_name.demodulize.underscore.tableize.singularize - end - - def label - @custom_field.name - end - - def prepare(field, class_name) - @custom_field = field - @class_name = class_name - dont_inherit :group_fields - db_field table_name - if field.list? && all_values_int?(field) - join_table list_join_table(field) - else - join_table default_join_table(field) - end - instance_eval(&on_prepare) - self - end - - ## - # HACK: CustomValues of lists MAY have non-integer values when the list - # contained invalid values. - def all_values_int?(field) - field.custom_values.pluck(:value).all? { |val| val.to_i > 0 } - rescue - false - end - - def list_join_table(field) - cast_as = SQL_TYPES[field.field_format] - cf_name = "custom_field#{field.id}" - - custom_values_table = CustomValue.table_name - custom_options_table = CustomOption.table_name - - <<-SQL - -- BEGIN Custom Field Join: #{cf_name} - LEFT OUTER JOIN ( - SELECT - CAST(co.value AS #{cast_as}) AS #{cf_name}, - cv.customized_type, - cv.custom_field_id, - cv.customized_id - FROM #{custom_values_table} cv - INNER JOIN #{custom_options_table} co - ON cv.custom_field_id = co.custom_field_id AND CAST(cv.value AS decimal(60,3)) = co.id - ) AS #{cf_name} - ON #{cf_name}.customized_type = 'WorkPackage' - - AND #{cf_name}.custom_field_id = #{field.id} - AND #{cf_name}.customized_id = entries.work_package_id - -- END Custom Field Join: #{cf_name} - SQL - end - - def default_join_table(field) - <<-SQL % [CustomValue.table_name, table_name, field.id, field.name, SQL_TYPES[field.field_format]] - -- BEGIN Custom Field Join: "%4$s" - LEFT OUTER JOIN ( - \tSELECT - \t\tCAST(value AS %5$s) AS %2$s, - \t\tcustomized_type, - \t\tcustom_field_id, - \t\tcustomized_id - \tFROM - \t\t%1$s) - AS %2$s - ON %2$s.customized_type = 'WorkPackage' - AND %2$s.custom_field_id = %3$d - AND %2$s.customized_id = entries.work_package_id - -- END Custom Field Join: "%4$s" - SQL - end - - def new(*) - fail "Only subclasses of #{self} should be instanciated." if factory? - super - end -end diff --git a/app/models/cost_query/filter.rb b/app/models/cost_query/filter.rb deleted file mode 100644 index 6bdd3c1c..00000000 --- a/app/models/cost_query/filter.rb +++ /dev/null @@ -1,48 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require "set" - -class CostQuery::Filter < Report::Filter - def self.all - @all ||= super + Set[ - CostQuery::Filter::ActivityId, - CostQuery::Filter::AssignedToId, - CostQuery::Filter::AuthorId, - CostQuery::Filter::CategoryId, - CostQuery::Filter::CostTypeId, - CostQuery::Filter::CreatedOn, - CostQuery::Filter::DueDate, - CostQuery::Filter::FixedVersionId, - CostQuery::Filter::WorkPackageId, - CostQuery::Filter::OverriddenCosts, - CostQuery::Filter::PriorityId, - CostQuery::Filter::ProjectId, - CostQuery::Filter::SpentOn, - CostQuery::Filter::StartDate, - CostQuery::Filter::StatusId, - CostQuery::Filter::Subject, - CostQuery::Filter::TypeId, - CostQuery::Filter::UpdatedOn, - CostQuery::Filter::UserId, - CostQuery::Filter::PermissionFilter, - *CostQuery::Filter::CustomFieldEntries.all - ] - end -end diff --git a/app/models/cost_query/filter/activity_id.rb b/app/models/cost_query/filter/activity_id.rb deleted file mode 100644 index 9d4bc17f..00000000 --- a/app/models/cost_query/filter/activity_id.rb +++ /dev/null @@ -1,28 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::ActivityId < Report::Filter::Base - def self.label - TimeEntry.human_attribute_name(:activity) - end - - def self.available_values(*) - TimeEntryActivity.order('name').pluck(:name, :id) - end -end diff --git a/app/models/cost_query/filter/assigned_to_id.rb b/app/models/cost_query/filter/assigned_to_id.rb deleted file mode 100644 index 6a27cd43..00000000 --- a/app/models/cost_query/filter/assigned_to_id.rb +++ /dev/null @@ -1,28 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::AssignedToId < CostQuery::Filter::UserId - use :null_operators - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:assigned_to) - end -end diff --git a/app/models/cost_query/filter/author_id.rb b/app/models/cost_query/filter/author_id.rb deleted file mode 100644 index dca1ca05..00000000 --- a/app/models/cost_query/filter/author_id.rb +++ /dev/null @@ -1,31 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::AuthorId < Report::Filter::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:author) - end - - def self.available_values(*) - CostQuery::Filter::UserId.available_values - end -end diff --git a/app/models/cost_query/filter/category_id.rb b/app/models/cost_query/filter/category_id.rb deleted file mode 100644 index af27a934..00000000 --- a/app/models/cost_query/filter/category_id.rb +++ /dev/null @@ -1,33 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::CategoryId < Report::Filter::Base - use :null_operators - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:category) - end - - def self.available_values(*) - categories = Category.where(project_id: Project.visible.map(&:id)) - categories.map { |c| ["#{c.project.name} - #{c.name} ", c.id] }.sort_by { |a| a.first.to_s + a.second.to_s } - end -end diff --git a/app/models/cost_query/filter/cost_object_id.rb b/app/models/cost_query/filter/cost_object_id.rb deleted file mode 100644 index 328ea5b2..00000000 --- a/app/models/cost_query/filter/cost_object_id.rb +++ /dev/null @@ -1,31 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::CostObjectId < Report::Filter::Base - join_table Project - applies_for :label_work_package_attributes - - def self.label - CostObject.model_name.human - end - - def self.available_values(*) - [[l(:caption_labor), -1]] + CostObject.order('name').pluck(:name, :id) - end -end diff --git a/app/models/cost_query/filter/cost_type_id.rb b/app/models/cost_query/filter/cost_type_id.rb deleted file mode 100644 index 3998bda2..00000000 --- a/app/models/cost_query/filter/cost_type_id.rb +++ /dev/null @@ -1,55 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::CostTypeId < Report::Filter::Base - extra_options :display - selectable false - - def self.label - WorkPackage.human_attribute_name(:cost_type) - end - - def initialize(child = nil, options = {}) - super - @display = options[:display] - end - - ## - # @Override - # Displayability is decided on the instance - def display? - return super if @display.nil? - @display - end - - def field - # prevent setting an extra cost type constraint - # WHERE cost_type_id IN (...) - # when money value is requested - if values == ["0"] - [] - else - super - end - end - - def self.available_values(*) - [[::I18n.t(:caption_labor), -1]] + CostType.order('name').pluck(:name, :id) - end -end diff --git a/app/models/cost_query/filter/created_on.rb b/app/models/cost_query/filter/created_on.rb deleted file mode 100644 index 2183cb61..00000000 --- a/app/models/cost_query/filter/created_on.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::CreatedOn < Report::Filter::Base - db_field 'entries.created_on' - use :time_operators - - def self.label - WorkPackage.human_attribute_name(:created_on) - end -end diff --git a/app/models/cost_query/filter/custom_field_entries.rb b/app/models/cost_query/filter/custom_field_entries.rb deleted file mode 100644 index 206b15ee..00000000 --- a/app/models/cost_query/filter/custom_field_entries.rb +++ /dev/null @@ -1,53 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::CustomFieldEntries < Report::Filter::Base - extend CostQuery::CustomFieldMixin - - on_prepare do - applies_for :label_work_package_attributes - # redmine internals just suck - case custom_field.field_format - when 'string', 'text' then use :string_operators - when 'list' then use :null_operators - when 'date' then use :time_operators - when 'int', 'float' then use :integer_operators - when 'bool' - @possible_values = [['true', 't'], ['false', 'f']] - use :null_operators - else - fail "cannot handle #{custom_field.field_format.inspect}" - end - end - - def self.available_values(*) - @possible_values || get_possible_values - end - - def self.get_possible_values - if custom_field.field_format == 'list' - # Treat list CFs values as string options again, since - # aggregation of groups are made by the values as well - # and otherwise, it won't work as a filter. - custom_field.possible_values.map { |co| [co.value, co.value] } - else - custom_field.possible_values - end - end -end diff --git a/app/models/cost_query/filter/due_date.rb b/app/models/cost_query/filter/due_date.rb deleted file mode 100644 index f16c8446..00000000 --- a/app/models/cost_query/filter/due_date.rb +++ /dev/null @@ -1,28 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::DueDate < Report::Filter::Base - use :time_operators - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:due_date) - end -end diff --git a/app/models/cost_query/filter/fixed_version_id.rb b/app/models/cost_query/filter/fixed_version_id.rb deleted file mode 100644 index 88d00941..00000000 --- a/app/models/cost_query/filter/fixed_version_id.rb +++ /dev/null @@ -1,33 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::FixedVersionId < Report::Filter::Base - use :null_operators - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:fixed_version) - end - - def self.available_values(*) - versions = Version.where(project_id: Project.visible.map(&:id)) - versions.map { |a| ["#{a.project.name} - #{a.name}", a.id] }.sort_by { |a| a.first.to_s + a.second.to_s } - end -end diff --git a/app/models/cost_query/filter/no_filter.rb b/app/models/cost_query/filter/no_filter.rb deleted file mode 100644 index d55f4c73..00000000 --- a/app/models/cost_query/filter/no_filter.rb +++ /dev/null @@ -1,28 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::NoFilter < Report::Filter::NoFilter - table_name 'entries' - dont_display! - singleton - - def sql_statement - CostQuery::SqlStatement.for_entries - end -end diff --git a/app/models/cost_query/filter/overridden_costs.rb b/app/models/cost_query/filter/overridden_costs.rb deleted file mode 100644 index 270aeb98..00000000 --- a/app/models/cost_query/filter/overridden_costs.rb +++ /dev/null @@ -1,32 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::OverriddenCosts < Report::Filter::Base - def self.label - CostEntry.human_attribute_name(:overridden_costs) - end - - def self.available_operators - ['y', 'n'].map(&:to_operator) - end - - def self.available_values(*) - [] - end -end diff --git a/app/models/cost_query/filter/permission_filter.rb b/app/models/cost_query/filter/permission_filter.rb deleted file mode 100644 index a47d1733..00000000 --- a/app/models/cost_query/filter/permission_filter.rb +++ /dev/null @@ -1,57 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::PermissionFilter < Report::Filter::Base - dont_display! - not_selectable! - db_field '' - singleton - - initialize_query_with { |query| query.filter to_s.demodulize.to_sym } - - def permission_statement(permission) - User.current.allowed_to_condition_with_project_id(permission).gsub(/(user|project)s?\.id/, '\1_id') - end - - def permission_for(type) - "((#{permission_statement :"view_own_#{type}_entries"} AND user_id = #{User.current.id}) " \ - "OR #{permission_statement :"view_#{type}_entries"})" - end - - def display_costs - "(#{permission_statement :view_hourly_rates} " \ - "AND #{permission_statement :view_cost_rates}) " \ - 'OR ' \ - "(#{permission_statement :view_own_hourly_rate} " \ - "AND type = 'TimeEntry' AND user_id = #{User.current.id}) " \ - 'OR ' \ - "(#{permission_statement :view_cost_rates} " \ - "AND type = 'CostEntry' AND user_id = #{User.current.id})" - end - - def sql_statement - super.tap do |query| - query.from.each_subselect do |sub| - sub.where permission_for(sub == query.from.first ? 'time' : 'cost') - sub.select.delete_if { |f| f.end_with? 'display_costs' } - sub.select display_costs: switch(display_costs => '1', else: 0) - end - end - end -end diff --git a/app/models/cost_query/filter/priority_id.rb b/app/models/cost_query/filter/priority_id.rb deleted file mode 100644 index 7484d6c4..00000000 --- a/app/models/cost_query/filter/priority_id.rb +++ /dev/null @@ -1,31 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::PriorityId < Report::Filter::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:priority) - end - - def self.available_values(*) - IssuePriority.order('position DESC').pluck(:name, :id) - end -end diff --git a/app/models/cost_query/filter/project_id.rb b/app/models/cost_query/filter/project_id.rb deleted file mode 100644 index c6f72852..00000000 --- a/app/models/cost_query/filter/project_id.rb +++ /dev/null @@ -1,48 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::ProjectId < Report::Filter::Base - db_field 'entries.project_id' - - def self.label - Project.model_name.human - end - - def self.available_operators - ['=', '!', '=_child_projects', '!_child_projects'].map(&:to_operator) - end - - ## - # Calculates the available values for this filter. - # Gives a map of [project_name, project_id, nesting_level_of_project]. - # The map is sorted such that projects appear in alphabetical order within a nesting level - # and so that descendant projects appear after their ancestors. - def self.available_values(*) - map = [] - ancestors = [] - Project.visible.sort_by(&:lft).each do |project| - while ancestors.any? && !project.is_descendant_of?(ancestors.last) - ancestors.pop - end - map << [project.name, project.id, { level: ancestors.size }] - ancestors << project - end - map - end -end diff --git a/app/models/cost_query/filter/spent_on.rb b/app/models/cost_query/filter/spent_on.rb deleted file mode 100644 index 10bec3f4..00000000 --- a/app/models/cost_query/filter/spent_on.rb +++ /dev/null @@ -1,26 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::SpentOn < Report::Filter::Base - use :time_operators - - def self.label - I18n.t(:label_spent_on_reporting) - end -end diff --git a/app/models/cost_query/filter/start_date.rb b/app/models/cost_query/filter/start_date.rb deleted file mode 100644 index e242aa20..00000000 --- a/app/models/cost_query/filter/start_date.rb +++ /dev/null @@ -1,28 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::StartDate < Report::Filter::Base - use :time_operators - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:start_date) - end -end diff --git a/app/models/cost_query/filter/status_id.rb b/app/models/cost_query/filter/status_id.rb deleted file mode 100644 index 1c5f611b..00000000 --- a/app/models/cost_query/filter/status_id.rb +++ /dev/null @@ -1,34 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -# we have to require this here because the operators would not be defined otherwise -require_dependency 'cost_query/operator' -class CostQuery::Filter::StatusId < Report::Filter::Base - available_operators 'c', 'o' - join_table WorkPackage, Status => [WorkPackage, :status] - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:status) - end - - def self.available_values(*) - Status.order('name').pluck(:name, :id) - end -end diff --git a/app/models/cost_query/filter/subject.rb b/app/models/cost_query/filter/subject.rb deleted file mode 100644 index 5065bad7..00000000 --- a/app/models/cost_query/filter/subject.rb +++ /dev/null @@ -1,28 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::Subject < Report::Filter::Base - use :string_operators - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:subject) - end -end diff --git a/app/models/cost_query/filter/tmonth.rb b/app/models/cost_query/filter/tmonth.rb deleted file mode 100644 index c10a2e6b..00000000 --- a/app/models/cost_query/filter/tmonth.rb +++ /dev/null @@ -1,30 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::Tmonth < Report::Filter::Base - use :integer_operators - - def self.label - I18n.t(:label_month_reporting) - end - - def self.available_values(*) - 1.upto(12).map { |i| [::I18n.t('date.month_names')[i], i] } - end -end diff --git a/app/models/cost_query/filter/tweek.rb b/app/models/cost_query/filter/tweek.rb deleted file mode 100644 index ca8273a4..00000000 --- a/app/models/cost_query/filter/tweek.rb +++ /dev/null @@ -1,30 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::Tweek < Report::Filter::Base - use :integer_operators - - def self.label - I18n.t(:label_week_reporting) - end - - def self.available_values(*) - 1.upto(53).map { |i| [i.to_s, i] } - end -end diff --git a/app/models/cost_query/filter/tyear.rb b/app/models/cost_query/filter/tyear.rb deleted file mode 100644 index 1091f791..00000000 --- a/app/models/cost_query/filter/tyear.rb +++ /dev/null @@ -1,30 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::Tyear < Report::Filter::Base - use :integer_operators - - def self.label - I18n.t(:label_year_reporting) - end - - def self.available_values(*) - 1970.upto(Date.today.year).map { |i| [i.to_s, i] }.reverse - end -end diff --git a/app/models/cost_query/filter/type_id.rb b/app/models/cost_query/filter/type_id.rb deleted file mode 100644 index 423ca58b..00000000 --- a/app/models/cost_query/filter/type_id.rb +++ /dev/null @@ -1,31 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::TypeId < Report::Filter::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:type) - end - - def self.available_values(*) - Type.order('name').pluck(:name, :id) - end -end diff --git a/app/models/cost_query/filter/updated_on.rb b/app/models/cost_query/filter/updated_on.rb deleted file mode 100644 index 99fdfe19..00000000 --- a/app/models/cost_query/filter/updated_on.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::UpdatedOn < Report::Filter::Base - db_field 'entries.updated_on' - use :time_operators - - def self.label - WorkPackage.human_attribute_name(:updated_on) - end -end diff --git a/app/models/cost_query/filter/user_id.rb b/app/models/cost_query/filter/user_id.rb deleted file mode 100644 index 906554a2..00000000 --- a/app/models/cost_query/filter/user_id.rb +++ /dev/null @@ -1,60 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::UserId < Report::Filter::Base - def self.label - WorkPackage.human_attribute_name(:user) - end - - def self.me_value - 'me'.freeze - end - - def transformed_values - # Map the special 'me' value - super - .map { |val| replace_me_value(val) } - .compact - end - - def replace_me_value(value) - return value unless value == CostQuery::Filter::UserId.me_value - - if User.current.logged? - User.current.id - else - nil - end - end - - def self.available_values(*) - # All users which are members in projects the user can see. - # Excludes the anonymous user - users = User.joins(members: :project) - .merge(Project.visible) - .not_builtin - .limit(100) - .select(User::USER_FORMATS_STRUCTURE[Setting.user_format].map(&:to_s) << :id) - .distinct - - values = users.map { |u| [u.name, u.id] } - values.unshift [::I18n.t(:label_me), me_value] if User.current.logged? - values - end -end diff --git a/app/models/cost_query/filter/work_package_id.rb b/app/models/cost_query/filter/work_package_id.rb deleted file mode 100644 index 48e98a37..00000000 --- a/app/models/cost_query/filter/work_package_id.rb +++ /dev/null @@ -1,54 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Filter::WorkPackageId < Report::Filter::Base - def self.label - WorkPackage.model_name.human - end - - def self.available_values(*) - work_packages = WorkPackage.where(project_id: Project.allowed_to(User.current, :view_work_packages)) - .order(:id) - .pluck(:id, :subject) - work_packages.map { |id, subject| [text_for_tuple(id, subject), id] } - end - - def self.available_operators - ['='].map(&:to_operator) - end - - ## - # Overwrites Report::Filter::Base self.label_for_value method - # to achieve a more performant implementation - def self.label_for_value(value) - return nil unless value.to_i.to_s == value.to_s # we expect an work_package-id - work_package = WorkPackage.find(value.to_i) - [text_for_work_package(work_package), work_package.id] if work_package and work_package.visible?(User.current) - end - - def self.text_for_tuple(id, subject) - str = "##{id} " - str << (subject.length > 30 ? subject.first(26) + '...' : subject) - end - - def self.text_for_work_package(i) - i = i.first if i.is_a? Array - text_for_touble(i.id, i.subject) - end -end diff --git a/app/models/cost_query/group_by.rb b/app/models/cost_query/group_by.rb deleted file mode 100644 index 9f12f37e..00000000 --- a/app/models/cost_query/group_by.rb +++ /dev/null @@ -1,46 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require "set" - -class CostQuery::GroupBy < Report::GroupBy - def self.all - @all ||= super + Set[ - CostQuery::GroupBy::ActivityId, - CostQuery::GroupBy::CostObjectId, - CostQuery::GroupBy::CostTypeId, - CostQuery::GroupBy::FixedVersionId, - CostQuery::GroupBy::WorkPackageId, - CostQuery::GroupBy::PriorityId, - CostQuery::GroupBy::ProjectId, - CostQuery::GroupBy::SpentOn, - CostQuery::GroupBy::SingletonValue, - CostQuery::GroupBy::Tmonth, - CostQuery::GroupBy::TypeId, - CostQuery::GroupBy::Tyear, - CostQuery::GroupBy::UserId, - CostQuery::GroupBy::Week, - CostQuery::GroupBy::AuthorId, - CostQuery::GroupBy::AssignedToId, - CostQuery::GroupBy::CategoryId, - CostQuery::GroupBy::StatusId, - *CostQuery::GroupBy::CustomFieldEntries.all - ] - end -end diff --git a/app/models/cost_query/group_by/activity_id.rb b/app/models/cost_query/group_by/activity_id.rb deleted file mode 100644 index fab3b180..00000000 --- a/app/models/cost_query/group_by/activity_id.rb +++ /dev/null @@ -1,24 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::ActivityId < Report::GroupBy::Base - def self.label - TimeEntry.human_attribute_name(:activity) - end -end diff --git a/app/models/cost_query/group_by/assigned_to_id.rb b/app/models/cost_query/group_by/assigned_to_id.rb deleted file mode 100644 index 71d937cc..00000000 --- a/app/models/cost_query/group_by/assigned_to_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::AssignedToId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:assigned_to) - end -end diff --git a/app/models/cost_query/group_by/author_id.rb b/app/models/cost_query/group_by/author_id.rb deleted file mode 100644 index a8082a32..00000000 --- a/app/models/cost_query/group_by/author_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::AuthorId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:author) - end -end diff --git a/app/models/cost_query/group_by/base.rb b/app/models/cost_query/group_by/base.rb deleted file mode 100644 index a3e520b9..00000000 --- a/app/models/cost_query/group_by/base.rb +++ /dev/null @@ -1,24 +0,0 @@ -#-- copyright -# ReportingEngine -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy - class Base < Report::GroupBy::Base - # Exists solely for +Report::Chainable#base?+ - end -end diff --git a/app/models/cost_query/group_by/category_id.rb b/app/models/cost_query/group_by/category_id.rb deleted file mode 100644 index 3856921d..00000000 --- a/app/models/cost_query/group_by/category_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::CategoryId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:category) - end -end diff --git a/app/models/cost_query/group_by/cost_object_id.rb b/app/models/cost_query/group_by/cost_object_id.rb deleted file mode 100644 index 441ceb63..00000000 --- a/app/models/cost_query/group_by/cost_object_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::CostObjectId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - CostObject.model_name.human - end -end diff --git a/app/models/cost_query/group_by/cost_type_id.rb b/app/models/cost_query/group_by/cost_type_id.rb deleted file mode 100644 index 9545b6fd..00000000 --- a/app/models/cost_query/group_by/cost_type_id.rb +++ /dev/null @@ -1,25 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::CostTypeId < Report::GroupBy::Base - - def self.label - CostType.model_name.human - end -end diff --git a/app/models/cost_query/group_by/custom_field_entries.rb b/app/models/cost_query/group_by/custom_field_entries.rb deleted file mode 100644 index c942f549..00000000 --- a/app/models/cost_query/group_by/custom_field_entries.rb +++ /dev/null @@ -1,24 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::CustomFieldEntries < Report::GroupBy::Base - applies_for :label_work_package_attributes - extend CostQuery::CustomFieldMixin - on_prepare { group_fields table_name } -end diff --git a/app/models/cost_query/group_by/fixed_version_id.rb b/app/models/cost_query/group_by/fixed_version_id.rb deleted file mode 100644 index b5769780..00000000 --- a/app/models/cost_query/group_by/fixed_version_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::FixedVersionId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:fixed_version) - end -end diff --git a/app/models/cost_query/group_by/priority_id.rb b/app/models/cost_query/group_by/priority_id.rb deleted file mode 100644 index 09966d0f..00000000 --- a/app/models/cost_query/group_by/priority_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::PriorityId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:priority) - end -end diff --git a/app/models/cost_query/group_by/project_id.rb b/app/models/cost_query/group_by/project_id.rb deleted file mode 100644 index a634bea6..00000000 --- a/app/models/cost_query/group_by/project_id.rb +++ /dev/null @@ -1,25 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::ProjectId < Report::GroupBy::Base - - def self.label - Project.model_name.human - end -end diff --git a/app/models/cost_query/group_by/ruby_aggregation.rb b/app/models/cost_query/group_by/ruby_aggregation.rb deleted file mode 100644 index 63b61dfb..00000000 --- a/app/models/cost_query/group_by/ruby_aggregation.rb +++ /dev/null @@ -1,32 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy - module RubyAggregation - def responsible_for_sql? - false - end - - ## - # @return [CostQuery::Result] aggregation - def compute_result - child.result.grouped_by(all_group_fields(false), type, group_fields) - end - end -end diff --git a/app/models/cost_query/group_by/singleton_value.rb b/app/models/cost_query/group_by/singleton_value.rb deleted file mode 100644 index 8fb10628..00000000 --- a/app/models/cost_query/group_by/singleton_value.rb +++ /dev/null @@ -1,22 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::SingletonValue < Report::GroupBy::SingletonValue - dont_display! -end diff --git a/app/models/cost_query/group_by/spent_on.rb b/app/models/cost_query/group_by/spent_on.rb deleted file mode 100644 index 100c1e99..00000000 --- a/app/models/cost_query/group_by/spent_on.rb +++ /dev/null @@ -1,24 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::SpentOn < Report::GroupBy::Base - def self.label - I18n.t(:label_spent_on_reporting) - end -end diff --git a/app/models/cost_query/group_by/sql_aggregation.rb b/app/models/cost_query/group_by/sql_aggregation.rb deleted file mode 100644 index 9bd36310..00000000 --- a/app/models/cost_query/group_by/sql_aggregation.rb +++ /dev/null @@ -1,30 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy - module SqlAggregation - include Report::GroupBy::SqlAggregation - - def sql_statement - super.tap do |sql| - sql.sum units: :units, real_costs: :real_costs, display_costs: :display_costs - end - end - end -end diff --git a/app/models/cost_query/group_by/status_id.rb b/app/models/cost_query/group_by/status_id.rb deleted file mode 100644 index 11c94217..00000000 --- a/app/models/cost_query/group_by/status_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::StatusId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:status) - end -end diff --git a/app/models/cost_query/group_by/tmonth.rb b/app/models/cost_query/group_by/tmonth.rb deleted file mode 100644 index 3561480d..00000000 --- a/app/models/cost_query/group_by/tmonth.rb +++ /dev/null @@ -1,25 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::Tmonth < Report::GroupBy::Base - - def self.label - I18n.t(:label_month_reporting) - end -end diff --git a/app/models/cost_query/group_by/tweek.rb b/app/models/cost_query/group_by/tweek.rb deleted file mode 100644 index 16555b1e..00000000 --- a/app/models/cost_query/group_by/tweek.rb +++ /dev/null @@ -1,25 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::Tweek < Report::GroupBy::Base - - def self.label - I18n.t(:label_week_reporting) - end -end diff --git a/app/models/cost_query/group_by/tyear.rb b/app/models/cost_query/group_by/tyear.rb deleted file mode 100644 index acd77df9..00000000 --- a/app/models/cost_query/group_by/tyear.rb +++ /dev/null @@ -1,25 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::Tyear < Report::GroupBy::Base - - def self.label - I18n.t(:label_year_reporting) - end -end diff --git a/app/models/cost_query/group_by/type_id.rb b/app/models/cost_query/group_by/type_id.rb deleted file mode 100644 index 9c7ee783..00000000 --- a/app/models/cost_query/group_by/type_id.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::TypeId < Report::GroupBy::Base - join_table WorkPackage - applies_for :label_work_package_attributes - - def self.label - WorkPackage.human_attribute_name(:type) - end -end diff --git a/app/models/cost_query/group_by/user_id.rb b/app/models/cost_query/group_by/user_id.rb deleted file mode 100644 index 1fede1a5..00000000 --- a/app/models/cost_query/group_by/user_id.rb +++ /dev/null @@ -1,25 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::UserId < Report::GroupBy::Base - - def self.label - WorkPackage.human_attribute_name(:user) - end -end diff --git a/app/models/cost_query/group_by/week.rb b/app/models/cost_query/group_by/week.rb deleted file mode 100644 index 11711507..00000000 --- a/app/models/cost_query/group_by/week.rb +++ /dev/null @@ -1,24 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::Week < Report::GroupBy::Base - def self.label - I18n.t(:label_week_reporting) - end -end diff --git a/app/models/cost_query/group_by/work_package_id.rb b/app/models/cost_query/group_by/work_package_id.rb deleted file mode 100644 index ef28bdd1..00000000 --- a/app/models/cost_query/group_by/work_package_id.rb +++ /dev/null @@ -1,25 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::GroupBy::WorkPackageId < Report::GroupBy::Base - - def self.label - WorkPackage.model_name.human - end -end diff --git a/app/models/cost_query/operator.rb b/app/models/cost_query/operator.rb deleted file mode 100644 index c15e724c..00000000 --- a/app/models/cost_query/operator.rb +++ /dev/null @@ -1,61 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Operator < Report::Operator - # Operators from Redmine - new "c", arity: 0, label: :label_closed do - def modify(query, field, *values) - raise "wrong field" if field.to_s.split('.').last != "status_id" - query.where "(#{Status.table_name}.is_closed = #{quoted_true})" - query - end - end - - new "o", arity: 0, label: :label_open do - def modify(query, field, *values) - raise "wrong field" if field.to_s.split('.').last != "status_id" - query.where "(#{Status.table_name}.is_closed = #{quoted_false})" - query - end - end - - new "=_child_projects", validate: :integers, label: :label_is_project_with_subprojects do - def modify(query, field, *values) - p_ids = [] - values.each do |value| - p_ids += ([value] << Project.find(value).descendants.map{ |p| p.id }) - end - "=".to_operator.modify query, field, p_ids - rescue ActiveRecord::RecordNotFound - query - end - end - - new "!_child_projects", validate: :integers, label: :label_is_not_project_with_subprojects do - def modify(query, field, *values) - p_ids = [] - values.each do |value| - p_ids += ([value] << Project.find(value).descendants.map{ |p| p.id }) - end - "!".to_operator.modify query, field, p_ids - rescue ActiveRecord::RecordNotFound - query - end - end -end diff --git a/app/models/cost_query/query_utils.rb b/app/models/cost_query/query_utils.rb deleted file mode 100644 index 997e0e5e..00000000 --- a/app/models/cost_query/query_utils.rb +++ /dev/null @@ -1,52 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module CostQuery::QueryUtils - include Redmine::I18n - include Report::QueryUtils - - def map_field(key, value) - case key.to_s - when "user_id" then value ? user_name(value.to_i) : '' - when "tweek", "tyear", "tmonth", /_id$/ then value.to_i - when "week" then value.to_i.divmod(100) - when /_(on|at)$/ then value ? value.to_dateish : Time.at(0) - when /^custom_field/ then value.to_s - when "singleton_value" then value.to_i - else super - end - end - - def user_name(id) - # we have no identity map... :( - cache[:user_name][id] ||= User.find(id).name - end - - ## - # Graceful, internationalized quoted string. - # - # @see quote_string - # @param [Object] str String to quote/translate - # @return [Object] Quoted, translated version - def quoted_label(ident) - "'#{quote_string l(ident)}'" - end - - propagate! -end diff --git a/app/models/cost_query/result.rb b/app/models/cost_query/result.rb deleted file mode 100644 index 54cc97f9..00000000 --- a/app/models/cost_query/result.rb +++ /dev/null @@ -1,57 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Result < Report::Result - module BaseAdditions - def inspect - "<##{self.class}: @fields=#{fields.inspect} @type=#{type.inspect} " \ - "@size=#{size} @count=#{count} @units=#{units} @real_costs=#{real_costs}>" - end - - def display_costs? - display_costs > 0 - end - end - - class Base < Report::Result::Base - include BaseAdditions - end - - class DirectResult < Report::Result::DirectResult - include BaseAdditions - def display_costs - self["display_costs"].to_i - end - - def real_costs - (self["real_costs"] || 0).to_d if display_costs? # FIXME: default value here? - end - end - - class WrappedResult < Report::Result::WrappedResult - include BaseAdditions - def display_costs - (sum_for :display_costs) >= 1 ? 1 : 0 - end - - def real_costs - sum_for :real_costs if display_costs? - end - end -end diff --git a/app/models/cost_query/sql_statement.rb b/app/models/cost_query/sql_statement.rb deleted file mode 100644 index bfceadcf..00000000 --- a/app/models/cost_query/sql_statement.rb +++ /dev/null @@ -1,119 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::SqlStatement < Report::SqlStatement - COMMON_FIELDS = %w[ - user_id project_id work_package_id rate_id - comments spent_on created_on updated_on tyear tmonth tweek - costs overridden_costs type - ] - - # flag to mark a reporting query consisting of a union of cost and time entries - attr_accessor :entry_union - - def initialize(table, desc = "") - super(table, desc) - @entry_union = false - end - - # this is a hack to ensure that additional joins added by filters do not result - # in additional columns being selected. - def to_s - select(['entries.*']) if select == ['*'] && group_by.empty? && self.entry_union - super - end - - ## - # Generates SqlStatement that maps time_entries and cost_entries to a common structure. - # - # Mapping for direct fields: - # - # Result | Time Entires | Cost entries - # --------------------------|--------------------------|-------------------------- - # id | id | id - # user_id | user_id | user_id - # project_id | project_id | project_id - # work_package_id | work_package_id | work_package_id - # rate_id | rate_id | rate_id - # comments | comments | comments - # spent_on | spent_on | spent_on - # created_on | created_on | created_on - # updated_on | updated_on | updated_on - # tyear | tyear | tyear - # tmonth | tmonth | tmonth - # tweek | tweek | tweek - # costs | costs | costs - # overridden_costs | overridden_costs | overridden_costs - # units | hours | units - # activity_id | activity_id | -1 - # cost_type_id | -1 | cost_type_id - # type | "TimeEntry" | "CostEntry" - # count | 1 | 1 - # - # Also: This _should_ handle joining activities and cost_types, as the logic differs for time_entries - # and cost_entries. - # - # @param [#table_name] model The model to map - # @return [CostQuery::SqlStatement] Generated statement - def self.unified_entry(model) - table = table_name_for model - new(table).tap do |query| - query.select COMMON_FIELDS - query.desc = "Subquery for #{table}" - query.select({ - count: 1, id: [model, :id], display_costs: 1, - real_costs: switch("#{table}.overridden_costs IS NULL" => [model, :costs], else: [model, :overridden_costs]), - week: iso_year_week(:spent_on, model), - singleton_value: 1 }) - #FIXME: build this subquery from a sql_statement - query.from "(SELECT *, #{typed :text, model.model_name.to_s} AS type FROM #{table}) AS #{table}" - send("unify_#{table}", query) - end - end - - ## - # Applies logic for mapping time entries to general entries structure. - # - # @param [CostQuery::SqlStatement] query The statement to adjust - def self.unify_time_entries(query) - query.select :activity_id, units: :hours, cost_type_id: -1 - query.select cost_type: quoted_label(:caption_labor) - end - - ## - # Applies logic for mapping cost entries to general entries structure. - # - # @param [CostQuery::SqlStatement] query The statement to adjust - def self.unify_cost_entries(query) - query.select :units, :cost_type_id, activity_id: -1 - query.select cost_type: "cost_types.name" - query.join CostType - end - - ## - # Generates a statement based on all entries (i.e. time entries and cost entries) mapped to the general entries structure, - # and therefore usable by filters and such. - # - # @return [CostQuery::SqlStatement] Generated statement - def self.for_entries - sql = new unified_entry(TimeEntry).union(unified_entry(CostEntry), "entries") - sql.entry_union = true - sql - end -end diff --git a/app/models/cost_query/table.rb b/app/models/cost_query/table.rb deleted file mode 100644 index a65dbe3a..00000000 --- a/app/models/cost_query/table.rb +++ /dev/null @@ -1,20 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class CostQuery::Table < Report::Table; end diff --git a/app/models/entry.rb b/app/models/entry.rb deleted file mode 100644 index 1eb8746b..00000000 --- a/app/models/entry.rb +++ /dev/null @@ -1,108 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module Entry - [TimeEntry, CostEntry].each { |e| e.send :include, self } - - class Delegator < ActiveRecord::Base - # Rails 3.2.13 delegates most of the methods defined here to an - # ActiveRecord::Relation (see active_record/querying.rb). - # Thus only implementing the four find_x methods isn't enough - # Rails 2.3 internally called these e.g. for all(). - # A quick fix is implementing all(), but we might need to reconsider how we - # do the delegation here if more methods were based on the four find_xs. - self.abstract_class = true - class << self - def ===(obj) - TimeEntry === obj or CostEntry === obj - end - - def calculate(type, *args) - a, b = TimeEntry.calculate(type, *args), CostEntry.calculate(type, *args) - case type - when :sum, :count then a + b - when :avg then (a + b) / 2 - when :min then [a, b].min - when :max then [a, b].max - else raise NotImplementedError - end - end - - undef_method :create, :update, :delete, :destroy, :new, :update_counters, - :increment_counter, :decrement_counter - - %w[update_all destroy_all delete_all].each do |meth| - define_method(meth) { |*args| send_all(meth, *args) } - end - - private - def all(*args) - ActiveSupport::Deprecation.warn('Passing arguments is deprecated') if args.any? - find_many :all # *args - end - - def count(*args) - ActiveSupport::Deprecation.warn('Passing arguments is deprecated') if args.any? - find_many :count # *args - end - - def find_initial(options) find_one :find_initial, options end - def find_last(options) find_one :find_last, options end - def find_every(options) find_many :find_every, options end - def find_from_ids(args, options) find_many :find_from_ids, options end - - def find_one(*args) - TimeEntry.send(*args) || CostEntry.send(*args) - end - - def find_many(*args) - TimeEntry.send(*args) + CostEntry.send(*args) - end - - def send_all(*args) - [TimeEntry.send(*args), CostEntry.send(*args)] - end - end - end - - def units - super - rescue NoMethodError - hours - end - - def cost_type - super - rescue NoMethodError - end - - def activity - super - rescue NoMethodError - end - - def activity_id - super - rescue NoMethodError - end - - def self.method_missing(*a, &b) - Delegator.send(*a, &b) - end -end diff --git a/app/views/cost_reports/_report_category.html.erb b/app/views/cost_reports/_report_category.html.erb deleted file mode 100644 index 53e7d4cb..00000000 --- a/app/views/cost_reports/_report_category.html.erb +++ /dev/null @@ -1,29 +0,0 @@ -<%#-- copyright -OpenProject Reporting Plugin - -Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 3. - -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. - -++#%> - -<%# needs locals: - report_type: symbol referring to helper methods of the sort #{report_type}_queries -%> - -<% queries = respond_to?(:"#{report_type}_queries") ? send(:"#{report_type}_queries") : [] %> -<% if queries.any? %> -

<%= l(:"label_#{report_type}_report_plural") %>

- <%= render :partial => "report_list", :locals => { :report_type => report_type, :queries => queries } %> -<% end -%> diff --git a/app/views/cost_reports/_report_list.html.erb b/app/views/cost_reports/_report_list.html.erb deleted file mode 100644 index 9da7c1e1..00000000 --- a/app/views/cost_reports/_report_list.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -<%#-- copyright -OpenProject Reporting Plugin - -Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 3. - -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. - -++#%> - -<% queries ||= respond_to?(:"#{report_type}_queries") ? send(:"#{report_type}_queries") : [] %> - diff --git a/app/views/cost_reports/_reporting_header.html.erb b/app/views/cost_reports/_reporting_header.html.erb deleted file mode 100644 index 122af3f0..00000000 --- a/app/views/cost_reports/_reporting_header.html.erb +++ /dev/null @@ -1,26 +0,0 @@ -<%#-- copyright -OpenProject Reporting Plugin - -Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 3. - -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. - -++#%> - -<% content_for :header_tags do %> - <%= javascript_include_tag "reporting_engine/reporting_engine" %> - <%= javascript_include_tag "reporting/reporting" %> - <%= stylesheet_link_tag 'reporting_engine/reporting_engine' %> - <%= stylesheet_link_tag "reporting/reporting" %> -<% end %> diff --git a/app/views/cost_reports/index.html.erb b/app/views/cost_reports/index.html.erb deleted file mode 100644 index c65a64ad..00000000 --- a/app/views/cost_reports/index.html.erb +++ /dev/null @@ -1,50 +0,0 @@ -<%#-- copyright -OpenProject Reporting Plugin - -Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 3. - -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. - -++#%> - -<%= render :partial => 'reporting_header' %> - -<% if @custom_errors.present? %> - <% @custom_errors.each do |err| %> -
<%= err %>
- <% end %> -<% end %> - -<% html_title (@query.persisted? ? "#{l(:label_cost_report)}: #{@query.name}" : l(:label_new_report)) %> - -

- <%= render_widget Widget::Controls::QueryName, @query, :can_rename => allowed_to?(:rename, @query, current_user) %> -

-<%= render_widget Widget::Settings, @query, :cost_types => @cost_types, :selected_type_id => @unit_id %> - -
- <%= render_widget Widget::Table, @query %> -
-
 
-

- <%= l(:text_costs_are_rounded_note) %> - <%= "
#{l(:information_restricted_depending_on_permission)}".html_safe if !User.current.admin?%> -

-<%= call_hook(:view_cost_report_table_bottom) %> - -<% content_for :sidebar do %> - <% [:private, :public].each do |type| %> - <%= render :partial => "report_category", :locals => { :report_type => type } %> - <% end %> -<% end -%> diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml deleted file mode 100644 index 1e9799a7..00000000 --- a/config/locales/crowdin/ar.yml +++ /dev/null @@ -1,49 +0,0 @@ -ar: - button_save_as: "حفظ التقرير بشكل..." - comments: "التعليق" - cost_reports_title: "تقارير التكلفة" - label_cost_report: "تقرير التكلفة" - description_drill_down: "أظهر التفاصيل" - description_filter_selection: "الاختيار" - description_multi_select: "أظهر الاختيار المتعدد" - description_remove_filter: "أَزِل عامل التصفية" - information_restricted_depending_on_permission: "اعتمادًا على الأذونات الخاصة بك، قد تحتوي هذه الصفحة على معلومات مقيّدة." - label_click_to_edit: "اضغط للتعديل." - label_closed: "مغلق" - label_columns: "الأعمدة" - label_cost_entry_attributes: "ميزات قيد التكلفة" - label_days_ago: "خلال الأيام الماضية" - label_entry: "قيد التكلفة" - label_filter_text: "تصفية النص" - label_filter_value: "القيمة" - label_filters: "عامل التصفية" - label_greater: ">" - label_is_not_project_with_subprojects: "لا (تشمل المشاريع الفرعية)" - label_is_project_with_subprojects: "هو (يشمل المشاريع الفرعية)" - label_work_package_attributes: "سمات مجموعة العمل" - label_less: "<" - label_money: "القيمة النقدية" - label_month_reporting: "شهر (قضى)" - label_new_report: "تقرير التكلفة الجديدة" - label_open: "افتح" - label_operator: "العامل" - label_private_report_plural: "تقارير التكلفة الخاصة" - label_progress_bar_explanation: "جاري إعداد التقرير..." - label_public_report_plural: "تقارير التكلفة العامة" - label_really_delete_question: "هل أنت متأكد من أنك تريد حذف هذا التقرير؟" - label_rows: "الصفوف" - label_saving: "جاري الحفظ ..." - label_spent_on_reporting: "التاريخ (قضى)" - label_sum: "المجموع" - label_units: "الوحدات" - label_week_reporting: "الأسبوع (قضى)" - label_year_reporting: "السنة (قضت)" - load_query_question: "سيكون للتقرير %{size} من خلايا الجدول، وقد يستغرق بعض الوقت للتقديم. هل ما زلت تريد المحاولة لتقديمه؟" - permission_save_cost_reports: "احفظ تقارير التكلفة العامة" - permission_save_private_cost_reports: "احفظ تقارير التكلفة الخاصة" - project_module_reporting_module: "تقارير التكلفة" - text_costs_are_rounded_note: "القيم المعروضة مدوّرة. تستند كل الحسابات على قيم غير مدوّرة." - toggle_multiselect: "تفعيل/تعطيل الاختيار المتعدد" - units: "الوحدات" - validation_failure_date: "ليس تاريخًا صالحًا" - validation_failure_integer: "ليس عددًا صحيحًا صالحًا" diff --git a/config/locales/crowdin/da.yml b/config/locales/crowdin/da.yml deleted file mode 100644 index fa51d2e5..00000000 --- a/config/locales/crowdin/da.yml +++ /dev/null @@ -1,49 +0,0 @@ -da: - button_save_as: "Gem rapport som..." - comments: "Kommentér" - cost_reports_title: "Omkostningsrapporter" - label_cost_report: "Omkostningsrapport" - description_drill_down: "Vis detaljer" - description_filter_selection: "Markering" - description_multi_select: "Vis flere markeringer" - description_remove_filter: "Fjern filter" - information_restricted_depending_on_permission: "Afhængigt af dine tilladelser kan denne side indeholde oplysninger du ikke kan se." - label_click_to_edit: "Klik for at redigere." - label_closed: "lukket" - label_columns: "Kolonner" - label_cost_entry_attributes: "Egenskaber for omkostningsposter" - label_days_ago: "i løbet af de seneste dage" - label_entry: "Omkostningspostering" - label_filter_text: "Filtertekst" - label_filter_value: "Værdi" - label_filters: "Filter" - label_greater: ">" - label_is_not_project_with_subprojects: "findes ikke (inkluderer underprojekter)" - label_is_project_with_subprojects: "findes (inkluderer underprojekter)" - label_work_package_attributes: "Egenskaber for arbejdspakker" - label_less: "<" - label_money: "Kontantværdi" - label_month_reporting: "Måned (Brugt)" - label_new_report: "Ny omkostningsrapport" - label_open: "åben" - label_operator: "Operator" - label_private_report_plural: "Privat omkostningsrapporter" - label_progress_bar_explanation: "Opbygger rapport..." - label_public_report_plural: "Offentlig omkostningsrapport" - label_really_delete_question: "Er du sikker på du vil slette denne rapport?" - label_rows: "Rækker" - label_saving: "Gemmer..." - label_spent_on_reporting: "Dato (Brugt)" - label_sum: "Sum" - label_units: "Enheder" - label_week_reporting: "Uge (Brugt)" - label_year_reporting: "År (Brugt)" - load_query_question: "Rapporten vil få %{size} celler og kan tage nogen tid at optegne. Ønsker du stadig at se den?" - permission_save_cost_reports: "Gem offentlig omkostningsrapport" - permission_save_private_cost_reports: "Gem privat omkostningsrapport" - project_module_reporting_module: "Omkostningsrapporter" - text_costs_are_rounded_note: "De viste værdier er afrundede. Alle beregninger udføres med de præcise værdier." - toggle_multiselect: "aktivér/deaktivér mulighed for valg af flere" - units: "Enheder" - validation_failure_date: "er ikke en gyldig dato" - validation_failure_integer: "er ikke et gyldigt heltal" diff --git a/config/locales/crowdin/de.yml b/config/locales/crowdin/de.yml deleted file mode 100644 index a26738c3..00000000 --- a/config/locales/crowdin/de.yml +++ /dev/null @@ -1,49 +0,0 @@ -de: - button_save_as: "Speichern unter ..." - comments: "Kommentar" - cost_reports_title: "Kostenauswertungen" - label_cost_report: "Kostenauswertung" - description_drill_down: "Details anzeigen" - description_filter_selection: "Auswahl" - description_multi_select: "Mehrfachauswahl anzeigen" - description_remove_filter: "Filter entfernen" - information_restricted_depending_on_permission: "Abhängig von Ihren Berechtigungen können die Informationen auf dieser Seite eingeschränkt sein." - label_click_to_edit: "Zum Bearbeiten hier klicken." - label_closed: "Geschlossen" - label_columns: "Spalten" - label_cost_entry_attributes: "Attribute am Kosteneintrag" - label_days_ago: "in den letzten Tagen" - label_entry: "Kosteneintrag" - label_filter_text: "Filtertext" - label_filter_value: "Wert" - label_filters: "Filter" - label_greater: ">" - label_is_not_project_with_subprojects: "ist nicht (mit Unterprojekten)" - label_is_project_with_subprojects: "ist (mit Unterprojekten)" - label_work_package_attributes: "Attribute am Ticket" - label_less: "<" - label_money: "Geldwert" - label_month_reporting: "Monat der Buchung" - label_new_report: "Neue Kostenauswertung" - label_open: "Offen" - label_operator: "Operator" - label_private_report_plural: "Persönliche Kostenauswertungen" - label_progress_bar_explanation: "Kostenauswertung wird erstellt ..." - label_public_report_plural: "Gemeinsame Kostenauswertungen" - label_really_delete_question: "Diese Kostenauswertung wirklich löschen?" - label_rows: "Zeilen" - label_saving: "Speichern..." - label_spent_on_reporting: "Datum der Buchung" - label_sum: "Summe" - label_units: "Einheiten" - label_week_reporting: "Woche der Buchung" - label_year_reporting: "Jahr der Buchung" - load_query_question: "Die Kostenauswertung wird %{size} Tabellen-Zellen haben, was sehr rechenintensiv sein kann. Wollen Sie dennoch versuchen, die Kostenauswertung durch zu führen?" - permission_save_cost_reports: "Speichern gemeinsamer Kostenauswertungen" - permission_save_private_cost_reports: "Speichern persönlicher Kostenauswertungen" - project_module_reporting_module: "Kostenauswertungen" - text_costs_are_rounded_note: "Die angezeigten Werte sind gerundet. Alle Berechnungen basieren auf ungerundeten Werten." - toggle_multiselect: "Mehrfachauswahl aktivieren/deaktivieren" - units: "Einheiten" - validation_failure_date: "ist kein gültiges Datum" - validation_failure_integer: "ist keine ganze Zahl" diff --git a/config/locales/crowdin/es-ES.yml b/config/locales/crowdin/es-ES.yml deleted file mode 100644 index 68993fea..00000000 --- a/config/locales/crowdin/es-ES.yml +++ /dev/null @@ -1,49 +0,0 @@ -es: - button_save_as: "Guardar informe como..." - comments: "Comentario" - cost_reports_title: "Reportes de costo" - label_cost_report: "Reporte de costo" - description_drill_down: "Mostrar detalles" - description_filter_selection: "Selección" - description_multi_select: "Mostrar selección múltiple" - description_remove_filter: "Eliminar filtro" - information_restricted_depending_on_permission: "Dependiendo de sus permisos esta página podría contener información restringida." - label_click_to_edit: "Haga clic para editar." - label_closed: "cerrado" - label_columns: "Columnas" - label_cost_entry_attributes: "Atributos de entrada de costos" - label_days_ago: "durante los últimos días" - label_entry: "Entrada de costo" - label_filter_text: "Filtrar texto" - label_filter_value: "Valor" - label_filters: "Filtrar" - label_greater: ">" - label_is_not_project_with_subprojects: "no (incluye subproyectos)" - label_is_project_with_subprojects: "es (incluye subproyectos)" - label_work_package_attributes: "Atributos del paquetes de trabajo" - label_less: "<" - label_money: "Valor en efectivo" - label_month_reporting: "Mes (pasado)" - label_new_report: "Nuevo informe de costo" - label_open: "abierto" - label_operator: "Operador" - label_private_report_plural: "Informes de costo privados" - label_progress_bar_explanation: "Generando informe..." - label_public_report_plural: "Informes de costo públicos" - label_really_delete_question: "¿Está seguro que quiere eliminar esta publicación?" - label_rows: "Filas" - label_saving: "Guardando..." - label_spent_on_reporting: "Fecha (pasada)" - label_sum: "Suma" - label_units: "Unidades" - label_week_reporting: "Semana (pasada)" - label_year_reporting: "Año (pasado)" - load_query_question: "El informe tendrá %{size} celdas en la tabla y llevará algún tiempo que se complete. ¿Todavía quiere intentar representarlo?" - permission_save_cost_reports: "Guardar informes de costos públicos" - permission_save_private_cost_reports: "Guardar informes de costos privados" - project_module_reporting_module: "Reportes de costo" - text_costs_are_rounded_note: "Los valores mostrados se han redondeado. Todos los cálculos se basan en valores no redondeados." - toggle_multiselect: "activar/desactivar selección múltiple" - units: "Unidades" - validation_failure_date: "no es una fecha válida" - validation_failure_integer: "no es un entero válido" diff --git a/config/locales/crowdin/fi.yml b/config/locales/crowdin/fi.yml deleted file mode 100644 index 77b7450c..00000000 --- a/config/locales/crowdin/fi.yml +++ /dev/null @@ -1,49 +0,0 @@ -fi: - button_save_as: "Tallenna raportti nimellä..." - comments: "Kommentti" - cost_reports_title: "Kustannusraportit" - label_cost_report: "Kustannusraportti" - description_drill_down: "Näytä tiedot" - description_filter_selection: "Valinta" - description_multi_select: "Näytä monivalinta" - description_remove_filter: "Poista suodatin" - information_restricted_depending_on_permission: "Käyttöoikeuksistasi riippuen tämä sivu voi sisältää estettyä informaatioa." - label_click_to_edit: "Klikkaa muokataksesi." - label_closed: "suljettu" - label_columns: "Sarakkeet" - label_cost_entry_attributes: "Kustannussyötön parametrit" - label_days_ago: "viimeisen päivien aikana" - label_entry: "Kustannuskirjaus" - label_filter_text: "Suodata tekstiä" - label_filter_value: "Arvo" - label_filters: "Suodatin" - label_greater: ">" - label_is_not_project_with_subprojects: "ei ole (sisältää aliprojekteja)" - label_is_project_with_subprojects: "on (sisältää aliprojekteja)" - label_work_package_attributes: "Työnpaketin parametrit" - label_less: "<" - label_money: "Rahallinen arvo" - label_month_reporting: "Kuukausi (käytetty)" - label_new_report: "Uusi kustannusraportti" - label_open: "avoin" - label_operator: "Operaattori" - label_private_report_plural: "Yksityiset kustannusraportit" - label_progress_bar_explanation: "Luodaan raporttia..." - label_public_report_plural: "Yleisest kustannusraportit" - label_really_delete_question: "Haluat varmasti poistaa tämän raportin?" - label_rows: "Rivit" - label_saving: "Tallennetaan..." - label_spent_on_reporting: "Päivämäärä (käytetty)" - label_sum: "Yhteensä" - label_units: "Yksiköt" - label_week_reporting: "Viikko (käytetty)" - label_year_reporting: "Vuosi (käytetty)" - load_query_question: "Raportissa tulee olemaan %{size} solua ja sen luominen voi kentää jonkin aikaa. Haluatko silti kokeilla sen luomista?" - permission_save_cost_reports: "Tallenna julkiset kustannusraportit" - permission_save_private_cost_reports: "Tallenna yksityiset kustannusraportit" - project_module_reporting_module: "Kustannusraportit" - text_costs_are_rounded_note: "Näytetyt arvot ovat pyöristettyjä. Kaikki laskutoimitukset tehdään pyöristämättömillä arvoilla." - toggle_multiselect: "ota käyttöön/poista käytöstä monivalinta" - units: "Yksiköt" - validation_failure_date: "ei ole kelvollinen päivämäärä" - validation_failure_integer: "ei ole kelvollinen kokonaisluku" diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml deleted file mode 100644 index 0638e6d4..00000000 --- a/config/locales/crowdin/fr.yml +++ /dev/null @@ -1,49 +0,0 @@ -fr: - button_save_as: "Enregistrer le rapport sous…" - comments: "Commentaire" - cost_reports_title: "Rapports de coût" - label_cost_report: "Rapport de coût" - description_drill_down: "Afficher les détails" - description_filter_selection: "Sélection" - description_multi_select: "Voir la sélection multiple" - description_remove_filter: "Supprimer le filtre" - information_restricted_depending_on_permission: "Selon vos autorisations cette page peut contenir des informations restreintes." - label_click_to_edit: "Cliquez pour modifier." - label_closed: "fermé" - label_columns: "Colonnes" - label_cost_entry_attributes: "Attributs de l'entrée de coût" - label_days_ago: "au cours des derniers jours" - label_entry: "Entrée de coût" - label_filter_text: "Filtrer le texte" - label_filter_value: "Valeur" - label_filters: "Filtre" - label_greater: ">" - label_is_not_project_with_subprojects: "n'est pas (y compris les sous-projets)" - label_is_project_with_subprojects: "est (y compris les sous-projets)" - label_work_package_attributes: "Attributs du lot de travaux" - label_less: "<" - label_money: "Valeur marchande" - label_month_reporting: "Mois (passé)" - label_new_report: "Nouveau rapport de coût" - label_open: "ouvrir" - label_operator: "Opérateur" - label_private_report_plural: "Rapports privés de coûts" - label_progress_bar_explanation: "Rapport en cours de génération..." - label_public_report_plural: "Rapports publics de coûts" - label_really_delete_question: "Êtes-vous sûr de vouloir supprimer ce rapport ?" - label_rows: "Lignes" - label_saving: "Enregistrement en cours… ..." - label_spent_on_reporting: "Date (passée)" - label_sum: "Total " - label_units: "Unité" - label_week_reporting: "Semaine (passée)" - label_year_reporting: "Année (passée)" - load_query_question: "Ce rapport a %{size} cellules et peut prendre un certain temps à s'afficher. Êtes-vous sûr de vouloir l'afficher ?" - permission_save_cost_reports: "Enregistrer des rapports publics de coûts" - permission_save_private_cost_reports: "Enregistrer des rapports privés de coûts" - project_module_reporting_module: "Rapports de coût" - text_costs_are_rounded_note: "Les valeurs affichées sont arrondies. Tous les calculs sont basés sur les valeurs non arrondies." - toggle_multiselect: "activer/désactiver la sélection multiple" - units: "Unité" - validation_failure_date: "n'est pas une date valide" - validation_failure_integer: "n'est pas un nombre entier valide" diff --git a/config/locales/crowdin/he.yml b/config/locales/crowdin/he.yml deleted file mode 100644 index 94f4b3c9..00000000 --- a/config/locales/crowdin/he.yml +++ /dev/null @@ -1,49 +0,0 @@ -he: - button_save_as: "שמור דוח כ..." - comments: "הערה" - cost_reports_title: "דוחות עלות" - label_cost_report: "דוח עלות" - description_drill_down: "הצג פרטים" - description_filter_selection: "בחירה" - description_multi_select: "הצג בחירה מרובה" - description_remove_filter: "הסר מסנן" - information_restricted_depending_on_permission: "בהתאם להרשאות שלך, דף זה עשוי להכיל מידע מוגבל." - label_click_to_edit: "לחץ לעריכה." - label_closed: "סגור" - label_columns: "עמודות" - label_cost_entry_attributes: "תכונות עלות כניסה" - label_days_ago: "במהלך הימים האחרונים" - label_entry: "עלות כניסה" - label_filter_text: "תמליל של מסנן" - label_filter_value: "ערך" - label_filters: "מסנן" - label_greater: ">" - label_is_not_project_with_subprojects: "לא (כולל תת פרוייקטים)" - label_is_project_with_subprojects: "הוא (כולל תת פרוייקטים)" - label_work_package_attributes: "תכונות חבילת עבודה" - label_less: "<" - label_money: "ערך כספי" - label_month_reporting: "חודש (הוצא)" - label_new_report: "דוח עלות חדש" - label_open: "פתוח" - label_operator: "מפעיל" - label_private_report_plural: "דוחות עלות פרטיים" - label_progress_bar_explanation: "מפיק דוח..." - label_public_report_plural: "דוחות עלות צבוריים" - label_really_delete_question: "האם אתה בטוח שברצונך לבטל דוח זה?" - label_rows: "שורות" - label_saving: "שומר ..." - label_spent_on_reporting: "תאריך (הוצא)" - label_sum: "סכום" - label_units: "יחידות" - label_week_reporting: "שבוע (הוצא)" - label_year_reporting: "שנה (הוצאה)" - load_query_question: "הדוח יכיל %{size} תאים בטבלה והפקתו עשויה לקחת זמן מה. האם עדיין ברצונך לנסות להפיקו?" - permission_save_cost_reports: "שמור דוחות עלות צבוריים" - permission_save_private_cost_reports: "שמור דוחות עלות פרטיים" - project_module_reporting_module: "דוחות עלות" - text_costs_are_rounded_note: "הערכים המוצגים מעוגלים. כל החישובים מבוססים על ערכים שאינם מעוגלים." - toggle_multiselect: "הפעל/בטל הפעלה של בחירה מרובה" - units: "יחידות" - validation_failure_date: "אינו תאריך בר תוקף" - validation_failure_integer: "אינו מספר שלם חוקי" diff --git a/config/locales/crowdin/hr.yml b/config/locales/crowdin/hr.yml deleted file mode 100644 index 8e4a01e8..00000000 --- a/config/locales/crowdin/hr.yml +++ /dev/null @@ -1,49 +0,0 @@ -hr: - button_save_as: "Spremi izvješće kao..." - comments: "Komentar" - cost_reports_title: "Izvješća troškova" - label_cost_report: "Izvješće troška" - description_drill_down: "Prikaži detalje" - description_filter_selection: "Izbor" - description_multi_select: "Prikaži višeodabir" - description_remove_filter: "Ukloni filter" - information_restricted_depending_on_permission: "Ovisno o vašim pravima, ova stranica će prikazati ogranićene informacije." - label_click_to_edit: "Kliknite za uređivanje." - label_closed: "zaključeno" - label_columns: "Stupci" - label_cost_entry_attributes: "Atributi ulaznog troška" - label_days_ago: "tijekom posljednjih dana" - label_entry: "Ulazni trošak" - label_filter_text: "Filtriraj tekst" - label_filter_value: "Vrijednost" - label_filters: "Filter" - label_greater: ">" - label_is_not_project_with_subprojects: "nije (uključujući i podprojekte)" - label_is_project_with_subprojects: "je (uključujući podprojekte)" - label_work_package_attributes: "Atributi radnih paketa" - label_less: "<" - label_money: "Vrijednost gotovine" - label_month_reporting: "Mjeseci (utrošeno)" - label_new_report: "Izvješće novog troška" - label_open: "otvori" - label_operator: "Operator" - label_private_report_plural: "Izvješća privatnog troška" - label_progress_bar_explanation: "Generiranje izvješća..." - label_public_report_plural: "Izvješća javnog troška" - label_really_delete_question: "Da li ste sigurni da želite izbrisati ovo izvješće?" - label_rows: "Redci" - label_saving: "Spremanje ..." - label_spent_on_reporting: "Datum (utrošeno)" - label_sum: "Zbroj" - label_units: "Jedinice" - label_week_reporting: "Tjedan (utrošeno)" - label_year_reporting: "Godine (utrošeno)" - load_query_question: "Izvješće će imati %{size} veličinu tablice te će biti potrebno određeno vrijeme za prikaz. Da li želite prikazati ga i dalje?" - permission_save_cost_reports: "Spremi izvješća javnog troška" - permission_save_private_cost_reports: "Spremi izvješća privatnog troška" - project_module_reporting_module: "Izvješća troškova" - text_costs_are_rounded_note: "Sve prikazane vrijednosti su zaokružene. Svi izračuni temelje se na decimalnim vrijednostima." - toggle_multiselect: "aktiviraj/deaktiviraj višeodabir" - units: "Jedinice" - validation_failure_date: "nije valjan datum" - validation_failure_integer: "nije valjan integer" diff --git a/config/locales/crowdin/hu.yml b/config/locales/crowdin/hu.yml deleted file mode 100644 index 529de034..00000000 --- a/config/locales/crowdin/hu.yml +++ /dev/null @@ -1,49 +0,0 @@ -hu: - button_save_as: "Mentés másként..." - comments: "Megjegyzés" - cost_reports_title: "Költség jelentések" - label_cost_report: "Költség jelentés" - description_drill_down: "Részletek megjelenítése" - description_filter_selection: "Kijelölés" - description_multi_select: "Több kiválasztása" - description_remove_filter: "Szűrő eltávolítása" - information_restricted_depending_on_permission: "Ez az oldal engedélyektől függően korlátozott adatokat tartalmazhat." - label_click_to_edit: "Szerkesztéséhez kattintson ide." - label_closed: "lezárt" - label_columns: "Oszlopok" - label_cost_entry_attributes: "Költség tétel attribútumok" - label_days_ago: "az elmúlt napokban" - label_entry: "Költség tétel" - label_filter_text: "Szöveges szűrő" - label_filter_value: "Érték" - label_filters: "Szűrő" - label_greater: ">" - label_is_not_project_with_subprojects: "nem egyezik (alprojektekkel együtt)" - label_is_project_with_subprojects: "egyezik (alprojektekkel együtt)" - label_work_package_attributes: "Munkacsomag attribútumai" - label_less: "<" - label_money: "Készpénz érték" - label_month_reporting: "Hónap (eltöltött)" - label_new_report: "Új költség-jelentés" - label_open: "nyitva" - label_operator: "Operátor" - label_private_report_plural: "Privát költség jelentések" - label_progress_bar_explanation: "Jelentés létrehozása..." - label_public_report_plural: "Nyilvános költség jelentések" - label_really_delete_question: "Biztosan törli ezt a jelentést?" - label_rows: "Sorok" - label_saving: "Mentés..." - label_spent_on_reporting: "Dátum (eltöltött)" - label_sum: "Össz." - label_units: "Egységek" - label_week_reporting: "Hét (eltöltött)" - label_year_reporting: "Év (eltöltött)" - load_query_question: "A jelentés %{size} cellát fog tartalmazni, így eltarthat egy ideig az elkészítése. Továbbra is el szeretné készíteni?" - permission_save_cost_reports: "Nyilvános költség jelentés mentése" - permission_save_private_cost_reports: "Privát költség jelentés mentése" - project_module_reporting_module: "Költség jelentések" - text_costs_are_rounded_note: "A megjelenített értékek kerekítettek. Minden számítás alapját a pontos értékek képzik." - toggle_multiselect: "többes kijelölés be-/kikapcsolása" - units: "Egységek" - validation_failure_date: "nem érvényes dátum" - validation_failure_integer: "nem érvényes egész szám" diff --git a/config/locales/crowdin/id.yml b/config/locales/crowdin/id.yml deleted file mode 100644 index ba455958..00000000 --- a/config/locales/crowdin/id.yml +++ /dev/null @@ -1,49 +0,0 @@ -id: - button_save_as: "Simpan sebagai..." - comments: "Komentar" - cost_reports_title: "Pelaporan biaya" - label_cost_report: "Laporan biaya" - description_drill_down: "Lihat detail" - description_filter_selection: "Seleksi" - description_multi_select: "Tampilkan multiselect" - description_remove_filter: "Hapus Filter" - information_restricted_depending_on_permission: "Informasi yang tersedia pada laman ini disesuaikan dengan hak akses anda." - label_click_to_edit: "Klik untuk mengubah." - label_closed: "berakhir" - label_columns: "Kolom" - label_cost_entry_attributes: "Atrribut masukan biaya" - label_days_ago: "beberapa hari terakhir" - label_entry: "Masukan biaya" - label_filter_text: "Filter teks" - label_filter_value: "Nilai" - label_filters: "Filter" - label_greater: ">" - label_is_not_project_with_subprojects: "yang bukan (termasuk dalam subproyek)" - label_is_project_with_subprojects: "adalah (termasuk dalam subproyek)" - label_work_package_attributes: "Attribut work package" - label_less: "<" - label_money: "Nilai uang" - label_month_reporting: "#Bulan (Spent)" - label_new_report: "Buat laporan biaya" - label_open: "terbuka" - label_operator: "Operator" - label_private_report_plural: "Laporan biaya terbatas" - label_progress_bar_explanation: "Membuat laporan..." - label_public_report_plural: "Laporan biaya umum" - label_really_delete_question: "Laporan akan dihapus, anda yakin?" - label_rows: "Baris" - label_saving: "Menyimpan ..." - label_spent_on_reporting: "Tanggal (spent)" - label_sum: "Total" - label_units: "Units" - label_week_reporting: "Minggu (spent)" - label_year_reporting: "Tahun (Spent)" - load_query_question: "Proses laporan memiliki %{size} cell dan akan memakan waktu yang relatif lama. Apakah anda ingin melanjutkan?" - permission_save_cost_reports: "Simpan laporan biaya untuk umum" - permission_save_private_cost_reports: "Simpan laporan biaya untuk diri sendiri" - project_module_reporting_module: "Pelaporan biaya" - text_costs_are_rounded_note: "Tampilkan nilai pembulatan walaupun kalkulasi menggunakan nilai desimal." - toggle_multiselect: "aktif/non-aktif multiselect" - units: "Units" - validation_failure_date: "validasi tanggal gagal" - validation_failure_integer: "validasi bilangan bulat gagal" diff --git a/config/locales/crowdin/it.yml b/config/locales/crowdin/it.yml deleted file mode 100644 index fffe09ef..00000000 --- a/config/locales/crowdin/it.yml +++ /dev/null @@ -1,49 +0,0 @@ -it: - button_save_as: "Salvare il report come..." - comments: "Commento" - cost_reports_title: "Report costi" - label_cost_report: "Report costo" - description_drill_down: "Mostra dettagli" - description_filter_selection: "Selezione" - description_multi_select: "Visualizza multiselect" - description_remove_filter: "Rimuovi filtro" - information_restricted_depending_on_permission: "A seconda delle tue autorizzazioni, questa pagina visualizzare meno informazioni." - label_click_to_edit: "Premi per modificare." - label_closed: "chiuso" - label_columns: "Colonne" - label_cost_entry_attributes: "Attributi voce di costo" - label_days_ago: "durante gli ultimi giorni" - label_entry: "Voce di costo" - label_filter_text: "Filtro testo" - label_filter_value: "Valore" - label_filters: "Filtro" - label_greater: ">" - label_is_not_project_with_subprojects: "non è (include sottoprogetti)" - label_is_project_with_subprojects: "è (include sottoprogetti)" - label_work_package_attributes: "Attributi del pacchetto lavoro" - label_less: "<" - label_money: "Valore in contanti" - label_month_reporting: "Mese (passato)" - label_new_report: "Nuovo rapporto di costo" - label_open: "apri" - label_operator: "Operatore" - label_private_report_plural: "Report costo privato" - label_progress_bar_explanation: "Generazione Report..." - label_public_report_plural: "Report costo pubblico" - label_really_delete_question: "Sei sicuro di voler cancellare questo report?" - label_rows: "Righe" - label_saving: "Salvataggio in corso ..." - label_spent_on_reporting: "Data (passato)" - label_sum: "Somma" - label_units: "Unità di misura" - label_week_reporting: "Settimana (passato)" - label_year_reporting: "Anno (passato)" - load_query_question: "Il report avrà le celle della tabella del %{size} e potrebbe essere necessario del tempo per eseguire il rendering. Vuoi ancora tentare di eseguirne il rendering?" - permission_save_cost_reports: "Salva il report costi pubblici" - permission_save_private_cost_reports: "Salvare il report costi privati" - project_module_reporting_module: "Report costi" - text_costs_are_rounded_note: "Valori visualizzati sono arrotondati. Tutti i calcoli sono basati sui valori non arrotondati." - toggle_multiselect: "attivare/disattivare la multiselect" - units: "Unità di misura" - validation_failure_date: "non è una data valida" - validation_failure_integer: "non è un numero intero valido" diff --git a/config/locales/crowdin/ja.yml b/config/locales/crowdin/ja.yml deleted file mode 100644 index 4df2cff2..00000000 --- a/config/locales/crowdin/ja.yml +++ /dev/null @@ -1,49 +0,0 @@ -ja: - button_save_as: "名前を付けてレポートの保存" - comments: "コメント" - cost_reports_title: "コストレポート" - label_cost_report: "コストレポート" - description_drill_down: "詳細を表示" - description_filter_selection: "選択" - description_multi_select: "複数選択" - description_remove_filter: "絞り込みを外す" - information_restricted_depending_on_permission: "アクセス権に応じて、このページでは情報を制限されている場合があります。" - label_click_to_edit: "クリックして編集" - label_closed: "完了" - label_columns: "列" - label_cost_entry_attributes: "コストエントリの属性" - label_days_ago: "直近の日の間" - label_entry: "コストエントリ" - label_filter_text: "テキストの絞り込み" - label_filter_value: "値" - label_filters: "絞り込み" - label_greater: ">" - label_is_not_project_with_subprojects: "ではない (子プロジェクトを含む)" - label_is_project_with_subprojects: "は(サブプロジェクトを含む)" - label_work_package_attributes: "作業項目の属性" - label_less: "<" - label_money: "金額" - label_month_reporting: "月 (経過)" - label_new_report: "新しいコストレポート" - label_open: "未完了" - label_operator: "演算子" - label_private_report_plural: "マイコストレポート" - label_progress_bar_explanation: "レポートを生成中..." - label_public_report_plural: "共有コストレポート" - label_really_delete_question: "このレポートを削除してもよろしいですか?" - label_rows: "行" - label_saving: "保存中…" - label_spent_on_reporting: "日付 (経過)" - label_sum: "合計" - label_units: "単位" - label_week_reporting: "週 (経過)" - label_year_reporting: "年 (経過)" - load_query_question: "レポートは%{size}つセルを持つために、描画するに時間がかかる場合があります。描画してもよろしいですか?" - permission_save_cost_reports: "共有コストレポートを保存" - permission_save_private_cost_reports: "マイコストレポートを保存" - project_module_reporting_module: "コストレポート" - text_costs_are_rounded_note: "表示されている数字は四捨五入されています。すべての計算は非四捨五入の値に基づいています。" - toggle_multiselect: "複数選択を有効/無効にする" - units: "単位" - validation_failure_date: "は有効な日付ではありません。" - validation_failure_integer: "は有効な整数ではありません。" diff --git a/config/locales/crowdin/ko.yml b/config/locales/crowdin/ko.yml deleted file mode 100644 index fd973e4d..00000000 --- a/config/locales/crowdin/ko.yml +++ /dev/null @@ -1,49 +0,0 @@ -ko: - button_save_as: "다른 이름으로 보고서로 저장..." - comments: "코멘트" - cost_reports_title: "비용 보고서" - label_cost_report: "비용 보고서" - description_drill_down: "세부 정보 표시" - description_filter_selection: "선택" - description_multi_select: "다중 선택 표시" - description_remove_filter: "필터 제거" - information_restricted_depending_on_permission: "사용자 권한에 따라 이 페이지에 제한된 정보가 포함될 수 있습니다." - label_click_to_edit: "편집하려면 클릭하세요." - label_closed: "마감됨" - label_columns: "열" - label_cost_entry_attributes: "비용 항목 특성" - label_days_ago: "지난 기간(일) 중" - label_entry: "비용 항목" - label_filter_text: "텍스트 필터링" - label_filter_value: "값" - label_filters: "필터" - label_greater: ">" - label_is_not_project_with_subprojects: "일치하지 않음(하위 프로젝트 포함)" - label_is_project_with_subprojects: "일치함(하위 프로젝트 포함)" - label_work_package_attributes: "작업 패키지 특성" - label_less: "<" - label_money: "현금 가치" - label_month_reporting: "월(소비)" - label_new_report: "새 비용 보고서" - label_open: "열기" - label_operator: "연산자" - label_private_report_plural: "비공개 비용 보고서" - label_progress_bar_explanation: "보고서 생성 중..." - label_public_report_plural: "공용 비용 보고서" - label_really_delete_question: "이 보고서를 삭제하시겠습니까?" - label_rows: "행" - label_saving: "저장 중..." - label_spent_on_reporting: "날짜(소비)" - label_sum: "합계" - label_units: "단위" - label_week_reporting: "주(소비)" - label_year_reporting: "년(소비)" - load_query_question: "보고서에는 %{size}개 테이블 셀이 있고 렌더링하는 데 시간이 걸릴 수 있습니다. 렌더링하시겠습니까?" - permission_save_cost_reports: "공용 비용 보고서 저장" - permission_save_private_cost_reports: "비공개 비용 보고서 저장" - project_module_reporting_module: "비용 보고서" - text_costs_are_rounded_note: "표시된 값은 반올림됩니다. 모든 계산은 반올림되지 않은 값을 기반으로 합니다." - toggle_multiselect: "다중 선택 활성화/비활성화" - units: "단위" - validation_failure_date: "은(는) 유효한 날짜가 아닙니다." - validation_failure_integer: "은(는) 유효한 정수가 아닙니다." diff --git a/config/locales/crowdin/lt.yml b/config/locales/crowdin/lt.yml deleted file mode 100644 index d7ae0d33..00000000 --- a/config/locales/crowdin/lt.yml +++ /dev/null @@ -1,49 +0,0 @@ -lt: - button_save_as: "Įrašyti ataskaitą kaip..." - comments: "Komentaras" - cost_reports_title: "Kaštų ataskaitos" - label_cost_report: "Kaštų ataskaita" - description_drill_down: "Rodyti Išsamią informaciją" - description_filter_selection: "Pasirinkimas" - description_multi_select: "Rodyti multipasirinkimą" - description_remove_filter: "Pašalinti filtrą" - information_restricted_depending_on_permission: "Priklausomai nuo Jūsų teisių, šis puslapis gali turėti apribotos informacijos." - label_click_to_edit: "Spustelėkite, kad redaguoti." - label_closed: "uždaryta" - label_columns: "Stulpeliai" - label_cost_entry_attributes: "Kaštų įrašų atributai" - label_days_ago: "per pastarąsias dienas" - label_entry: "Kaštų įrašas" - label_filter_text: "Filtruoti tekstą" - label_filter_value: "Reikšmė" - label_filters: "Filtras" - label_greater: ">" - label_is_not_project_with_subprojects: "nėra (apima subprojektus)" - label_is_project_with_subprojects: "yra (apima subprojektus)" - label_work_package_attributes: "Darbų paketo atributai" - label_less: "<" - label_money: "Pinigų reikšmė" - label_month_reporting: "Mėnuo (praleista)" - label_new_report: "Nauja kaštų ataskaita" - label_open: "atverti" - label_operator: "Operatorius" - label_private_report_plural: "Privačių kaštų ataskaitos" - label_progress_bar_explanation: "Generuojama ataskaita..." - label_public_report_plural: "Viešų kaštų ataskaitos" - label_really_delete_question: "Ar Jūs tikri, kad norite ištrinti šią ataskaitą?" - label_rows: "Eilutės" - label_saving: "Išsaugoma ..." - label_spent_on_reporting: "Data (praleista)" - label_sum: "Suma" - label_units: "Vienetai" - label_week_reporting: "Savaitė (praleista)" - label_year_reporting: "Metai (praleista)" - load_query_question: "Ataskaita turės %{size} lentelės langelių ir gali užtrukti, kol bus paruošta. Ar Jūs dar vis norite pabandyti sukurti ją?" - permission_save_cost_reports: "Išsaugoti viešų kaštų ataskaitas" - permission_save_private_cost_reports: "Išsaugoti privačių kaštų ataskaitas" - project_module_reporting_module: "Kaštų ataskaitos" - text_costs_are_rounded_note: "Rodomos reikšmės yra suapvalintos. Visi apskaičiavimai remiasi nesuapvalintomis reikšmėmis." - toggle_multiselect: "įjungti/išjungti multipasirinkimą" - units: "Vienetai" - validation_failure_date: "nėra tinkama data" - validation_failure_integer: "nėra tinkamas sveikas skaičius" diff --git a/config/locales/crowdin/nl.yml b/config/locales/crowdin/nl.yml deleted file mode 100644 index b0b4e6d4..00000000 --- a/config/locales/crowdin/nl.yml +++ /dev/null @@ -1,49 +0,0 @@ -nl: - button_save_as: "Rapport opslaan als..." - comments: "Commentaar" - cost_reports_title: "Kostenrapporten" - label_cost_report: "Kostenrapport" - description_drill_down: "Details weergeven" - description_filter_selection: "Selectie" - description_multi_select: "Bekijk de meervoudige selectie" - description_remove_filter: "Filter verwijderen" - information_restricted_depending_on_permission: "Afhankelijk van uw rechten, kan de informatie op deze pagina beperkt zijn." - label_click_to_edit: "Klik om te bewerken." - label_closed: "gesloten" - label_columns: "Kolommen" - label_cost_entry_attributes: "Attributen van de kosteninvoer" - label_days_ago: "gedurende de laatste dagen" - label_entry: "Kosteninvoer" - label_filter_text: "Tekst filteren" - label_filter_value: "Waarde" - label_filters: "Filter" - label_greater: ">" - label_is_not_project_with_subprojects: "is niet (inclusief subprojecten)" - label_is_project_with_subprojects: "is (inclusief subprojecten)" - label_work_package_attributes: "Attributen van het werkpakket" - label_less: "<" - label_money: "Cash waarde" - label_month_reporting: "Maand (kosten)" - label_new_report: "Nieuwe kostenrapport" - label_open: "open" - label_operator: "Operator" - label_private_report_plural: "Privé kostenrapporten" - label_progress_bar_explanation: "Rapport aan het genereren..." - label_public_report_plural: "Publiek kostenrapporten" - label_really_delete_question: "Weet u zeker dat u dit rapport wilt verwijderen?" - label_rows: "Rijen" - label_saving: "Opslaan..." - label_spent_on_reporting: "Datum (kosten)" - label_sum: "Som" - label_units: "Eenheden" - label_week_reporting: "Week (kosten)" - label_year_reporting: "Jaar (kosten)" - load_query_question: "Het rapport bevat %{size} tabelcellen en kan enige tijd kosten om te renderen. Wilt u proberen het rapport toch uit te voeren?" - permission_save_cost_reports: "Bewaar publiek kostenrapporten" - permission_save_private_cost_reports: "Bewaar privé kostenrapporten" - project_module_reporting_module: "Kostenrapporten" - text_costs_are_rounded_note: "De getoonde waarden zijn afgerond. Alle berekeningen zijn op niet-afgeronde waarden gebaseerd." - toggle_multiselect: "activeer / deactiveer meervoudige selectie" - units: "Eenheden" - validation_failure_date: "is een ongeldige datum" - validation_failure_integer: "is een ongeldig getal" diff --git a/config/locales/crowdin/pl.yml b/config/locales/crowdin/pl.yml deleted file mode 100644 index b38e13d5..00000000 --- a/config/locales/crowdin/pl.yml +++ /dev/null @@ -1,49 +0,0 @@ -pl: - button_save_as: "Zapisz raport jako..." - comments: "Komentarz" - cost_reports_title: "Raporty kosztów" - label_cost_report: "Raport kosztów" - description_drill_down: "Pokaż szczegóły" - description_filter_selection: "Wybór" - description_multi_select: "Pokaż multiselect" - description_remove_filter: "Usuń filtr" - information_restricted_depending_on_permission: "W zależności od uprawnień ta strona może zawierać ograniczone informacje." - label_click_to_edit: "Kliknij, aby edytować." - label_closed: "Zamknięte" - label_columns: "Kolumny" - label_cost_entry_attributes: "Wejściowe parametry kosztów" - label_days_ago: "podczas ostatnich dni" - label_entry: "Parametr kosztów" - label_filter_text: "Filtr tekstu" - label_filter_value: "Wartość" - label_filters: "Filtr" - label_greater: ">" - label_is_not_project_with_subprojects: "nie jest (zawiera podprojekty)" - label_is_project_with_subprojects: "jest (zawiera podprojekty)" - label_work_package_attributes: "Atrybuty zadań" - label_less: "<" - label_money: "Wartość pieniężna" - label_month_reporting: "Miesiąc (wydatki)" - label_new_report: "Nowy raport kosztowy" - label_open: "Otwarte" - label_operator: "Operator" - label_private_report_plural: "Prywatny raport kosztów" - label_progress_bar_explanation: "Generowanie raportu..." - label_public_report_plural: "Publiczny raport kosztów" - label_really_delete_question: "Na pewno chcesz usunąć ten raport?" - label_rows: "Wierszy" - label_saving: "Zapisywanie ..." - label_spent_on_reporting: "Data (wydatki)" - label_sum: "Suma" - label_units: "Jednostki" - label_week_reporting: "Tygodniu (wydatki)" - label_year_reporting: "Roku (wydatki)" - load_query_question: "Raport będzie mieć komórki tabeli %{size} i przygotowanie go może zająć trochę czasu. Czy chcesz uruchomić raport?" - permission_save_cost_reports: "Zapisz publiczny raport kosztów" - permission_save_private_cost_reports: "Zapisz prywatny raport kosztów" - project_module_reporting_module: "Raporty kosztów" - text_costs_are_rounded_note: "Wyświetlane wartości są zaokrąglane. Wszystkie obliczenia opierają się na wartościach niezaokrąglonych." - toggle_multiselect: "włączyć/wyłączyć multiselect" - units: "Jednostki" - validation_failure_date: "to nie jest poprawna data" - validation_failure_integer: "to nie jest prawidłową liczbą całkowitą" diff --git a/config/locales/crowdin/pt-BR.yml b/config/locales/crowdin/pt-BR.yml deleted file mode 100644 index 2ae9022e..00000000 --- a/config/locales/crowdin/pt-BR.yml +++ /dev/null @@ -1,49 +0,0 @@ -pt-BR: - button_save_as: "Salvar relatório como..." - comments: "Comentário" - cost_reports_title: "Relatórios de custos" - label_cost_report: "Relatório de custos" - description_drill_down: "Exibir detalhes" - description_filter_selection: "Seleção" - description_multi_select: "Mostrar multiseleção" - description_remove_filter: "Remover filtro" - information_restricted_depending_on_permission: "Dependendo de suas permissões esta página pode conter informações restritas." - label_click_to_edit: "Clique para editar." - label_closed: "fechado" - label_columns: "Colunas" - label_cost_entry_attributes: "Atributos do custo de entrada" - label_days_ago: "durante os últimos dias" - label_entry: "Custo de entrada" - label_filter_text: "Filtro de texto" - label_filter_value: "Valor" - label_filters: "Filtro" - label_greater: ">" - label_is_not_project_with_subprojects: "não é (inclui subprojetos)" - label_is_project_with_subprojects: "é (inclui subprojetos)" - label_work_package_attributes: "Atributos do pacote de trabalho" - label_less: "<" - label_money: "Valor em dinheiro" - label_month_reporting: "Mês (gasto)" - label_new_report: "Novo relatório de custos" - label_open: "aberto" - label_operator: "Operador" - label_private_report_plural: "Relatórios privados de custos" - label_progress_bar_explanation: "Gerando relatório..." - label_public_report_plural: "Relatórios público de custos" - label_really_delete_question: "Tem certeza que deseja excluir este relatório?" - label_rows: "Linhas" - label_saving: "Salvando ..." - label_spent_on_reporting: "Data (gasto)" - label_sum: "Soma" - label_units: "Unidades" - label_week_reporting: "Semana (gasto)" - label_year_reporting: "Ano (gasto)" - load_query_question: "Relatório terá %{size} células da tabela e pode levar algum tempo para processar. Você ainda quer tentar processá-lo?" - permission_save_cost_reports: "Salvar relatórios públicos de custos" - permission_save_private_cost_reports: "Salvar relatórios privados de custos" - project_module_reporting_module: "Relatórios de custos" - text_costs_are_rounded_note: "Valores exibidos são arredondados. Todos os cálculos baseiam-se em valores não-arredondados." - toggle_multiselect: "ativar/desativar multiseleção" - units: "Unidades" - validation_failure_date: "não é uma data válida" - validation_failure_integer: "não é um valor inteiro válido" diff --git a/config/locales/crowdin/pt-PT.yml b/config/locales/crowdin/pt-PT.yml deleted file mode 100644 index ab9fd181..00000000 --- a/config/locales/crowdin/pt-PT.yml +++ /dev/null @@ -1,49 +0,0 @@ -pt: - button_save_as: "Guardar relatório como..." - comments: "Comentário" - cost_reports_title: "Relatórios de custos" - label_cost_report: "Relatório de custo" - description_drill_down: "Mostrar detalhes" - description_filter_selection: "Seleção" - description_multi_select: "Mostrar multiseleção" - description_remove_filter: "Remover filtro" - information_restricted_depending_on_permission: "Dependendo das suas permissões, esta página pode conter informações restritas." - label_click_to_edit: "Clique para editar." - label_closed: "fechado" - label_columns: "Colunas" - label_cost_entry_attributes: "Atributos de entrada de custo" - label_days_ago: "durante os últimos dias" - label_entry: "Entrada de custo" - label_filter_text: "Filtrar texto" - label_filter_value: "Valor" - label_filters: "Filtro" - label_greater: ">" - label_is_not_project_with_subprojects: "não é (inclui subprojetos)" - label_is_project_with_subprojects: "é (inclui subprojetos)" - label_work_package_attributes: "Atributos do pacote de trabalho" - label_less: "<" - label_money: "Valor em dinheiro" - label_month_reporting: "Mês (gasto)" - label_new_report: "Novo relatório de custos" - label_open: "abrir" - label_operator: "Operador" - label_private_report_plural: "Relatórios de custos privados" - label_progress_bar_explanation: "A gerar relatório..." - label_public_report_plural: "Relatórios de custos públicos" - label_really_delete_question: "Tem a certeza que quer apagar este relatório?" - label_rows: "Linhas" - label_saving: "A guardar..." - label_spent_on_reporting: "Data (gasto)" - label_sum: "Soma" - label_units: "Unidades" - label_week_reporting: "Semana (gasto)" - label_year_reporting: "Ano (gasto)" - load_query_question: "O relatório terá %{size} células da tabela e pode levar algum tempo a processar. Quer tentar processá-lo?" - permission_save_cost_reports: "Guardar relatórios de custos públicos" - permission_save_private_cost_reports: "Guardar relatórios de custos privados" - project_module_reporting_module: "Relatórios de custos" - text_costs_are_rounded_note: "Os valores exibidos são arredondados. Todos os cálculos se baseiam nos valores não-arredondados." - toggle_multiselect: "ativar/desativar multiseleção" - units: "Unidades" - validation_failure_date: "não é uma data válida" - validation_failure_integer: "não é um número inteiro válido" diff --git a/config/locales/crowdin/ro.yml b/config/locales/crowdin/ro.yml deleted file mode 100644 index 03fc7185..00000000 --- a/config/locales/crowdin/ro.yml +++ /dev/null @@ -1,49 +0,0 @@ -ro: - button_save_as: "Salvare raport ca..." - comments: "Comentariu" - cost_reports_title: "Rapoarte de cost" - label_cost_report: "Raport de cost" - description_drill_down: "Afișare detalii" - description_filter_selection: "Selecție" - description_multi_select: "Afișare selecție multiplă" - description_remove_filter: "Eliminare filtre" - information_restricted_depending_on_permission: "În funcție de permisiunile dumneavoastră, această pagină poate conține informații restricționate." - label_click_to_edit: "Click pentru editare." - label_closed: "închis" - label_columns: "Coloane" - label_cost_entry_attributes: "Atribute poziție cost" - label_days_ago: "în ultimele zile" - label_entry: "Poziție cost" - label_filter_text: "Text filtrare" - label_filter_value: "Valoare" - label_filters: "Filtru" - label_greater: ">" - label_is_not_project_with_subprojects: "nu este (incluzând subproiecte)" - label_is_project_with_subprojects: "este (incluzând subproiecte)" - label_work_package_attributes: "Atribute pachet de lucru" - label_less: "<" - label_money: "Valoare monetară" - label_month_reporting: "Lună (consumată)" - label_new_report: "Raport de cost nou" - label_open: "deschis" - label_operator: "Operator" - label_private_report_plural: "Rapoarte de cost private" - label_progress_bar_explanation: "Raport în curs de generare..." - label_public_report_plural: "Rapoarte de cost publice" - label_really_delete_question: "Sunteți sigur că doriți să ștergeți acest raport?" - label_rows: "Rânduri" - label_saving: "Salvare în curs..." - label_spent_on_reporting: "Data (consumată)" - label_sum: "Sumă" - label_units: "Unități" - label_week_reporting: "Săptămână (consumată)" - label_year_reporting: "An (consumat)" - load_query_question: "Raportul va avea %{size} de celule şi e posibil ca generarea să dureze un timp. Sunteți sigur că doriți generarea?" - permission_save_cost_reports: "Salvare rapoarte de cost publice" - permission_save_private_cost_reports: "Salvare rapoarte de cost private" - project_module_reporting_module: "Rapoarte de cost" - text_costs_are_rounded_note: "Valorile afișate sunt rotunjite. Toate calculele sunt bazate pe valorile nerotunjite." - toggle_multiselect: "activare/dezactivare selecție multiplă" - units: "Unități" - validation_failure_date: "nu e o dată validă" - validation_failure_integer: "nu e un întreg valid" diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml deleted file mode 100644 index 82d9cfe3..00000000 --- a/config/locales/crowdin/ru.yml +++ /dev/null @@ -1,49 +0,0 @@ -ru: - button_save_as: "Сохранить отчет как..." - comments: "Комментарий" - cost_reports_title: "Стоимость отчетов" - label_cost_report: "Стоимость отчета" - description_drill_down: "Показать в деталях" - description_filter_selection: "Выбор" - description_multi_select: "Показать множественный выбор" - description_remove_filter: "Убрать фильтрацию" - information_restricted_depending_on_permission: "В зависимости от вашего разрешения, эта страница может содержать закрытую информацию." - label_click_to_edit: "Щелкнуть для изменения." - label_closed: "закрыто" - label_columns: "Столбцы" - label_cost_entry_attributes: "Стоимость входных атрибутов" - label_days_ago: "в последние дни" - label_entry: "Стоимость входа" - label_filter_text: "Фильтровать текст" - label_filter_value: "Значение" - label_filters: "Фильтровать" - label_greater: ">" - label_is_not_project_with_subprojects: "нет (включая подпроекты)" - label_is_project_with_subprojects: "есть (включая подпроекты)" - label_work_package_attributes: "Атрибуты рабочего пакета" - label_less: "<" - label_money: "Денежная стоимость" - label_month_reporting: "Месяц (Потрачено)" - label_new_report: "Новый отчет о затратах" - label_open: "открыть" - label_operator: "Оператор" - label_private_report_plural: "Частный отчет о затратах" - label_progress_bar_explanation: "Создание отчета..." - label_public_report_plural: "Публичный отчет о затратах" - label_really_delete_question: "Вы действительно хотите удалить этот отчет?" - label_rows: "Строк" - label_saving: "Сохранение ..." - label_spent_on_reporting: "Дата (Потрачено)" - label_sum: "Сумма" - label_units: "Модули" - label_week_reporting: "Неделя (Потрачено)" - label_year_reporting: "Год (потрачено)" - load_query_question: "Отчет будет иметь таблицу из %{size} ячеек и может потребоваться некоторое время для его визуализации. Вы все еще хотите попробовать это?" - permission_save_cost_reports: "Сохранить отчеты о публичных расходах" - permission_save_private_cost_reports: "Сохранить отчеты о частных расходах" - project_module_reporting_module: "Стоимость отчетов" - text_costs_are_rounded_note: "При отображении значения округляются. В расчетах используются неокругляемые значения." - toggle_multiselect: "активировать/деактивировать множественный выбор" - units: "Модули" - validation_failure_date: "не является допустимой датой" - validation_failure_integer: "не является допустимым целым числом" diff --git a/config/locales/crowdin/sv-SE.yml b/config/locales/crowdin/sv-SE.yml deleted file mode 100644 index 40fd3411..00000000 --- a/config/locales/crowdin/sv-SE.yml +++ /dev/null @@ -1,49 +0,0 @@ -sv: - button_save_as: "Spara rapporten som..." - comments: "Kommentar" - cost_reports_title: "Kostnadsrapporter" - label_cost_report: "Kostnadsrapport" - description_drill_down: "Visa detaljer" - description_filter_selection: "Urval" - description_multi_select: "Visa flerval" - description_remove_filter: "Ta bort filter" - information_restricted_depending_on_permission: "Beroende på dina behörigheter kan denna sida innehålla begränsad information." - label_click_to_edit: "Klicka för att ändra." - label_closed: "stängd" - label_columns: "Kolumner" - label_cost_entry_attributes: "Kostnadspostattribut" - label_days_ago: "under de senaste dagarna" - label_entry: "Kostnadspost" - label_filter_text: "Filtrera text" - label_filter_value: "Värde" - label_filters: "Filter" - label_greater: ">" - label_is_not_project_with_subprojects: "är inte (inkluderar delprojekt)" - label_is_project_with_subprojects: "är (inkluderar delprojekt)" - label_work_package_attributes: "Arbetspaketsattribut" - label_less: "<" - label_money: "Kontantvärde" - label_month_reporting: "Månad (spenderade)" - label_new_report: "Nya kostnadsrapport" - label_open: "öppen" - label_operator: "Operator" - label_private_report_plural: "Privata kostnadsrapporter" - label_progress_bar_explanation: "Genererar rapport..." - label_public_report_plural: "Offentliga kostnadsrapporter" - label_really_delete_question: "Är du säker på att du vill ta bort denna rapport?" - label_rows: "Rader" - label_saving: "Sparar ..." - label_spent_on_reporting: "Datum (spenderade)" - label_sum: "Summa" - label_units: "Enheter" - label_week_reporting: "Vecka (spenderade)" - label_year_reporting: "År (spenderade)" - load_query_question: "Rapporten kommer att ha %{size} celler och kan ta lite tid att skapa. Vill du prova att skapa den ändå?" - permission_save_cost_reports: "Spara offentliga kostnadsrapporter" - permission_save_private_cost_reports: "Spara privata kostnadsrapporter" - project_module_reporting_module: "Kostnadsrapporter" - text_costs_are_rounded_note: "Visade värden är avrundade. Alla beräkningar är baserade på de icke-avrundade värdena." - toggle_multiselect: "aktivera/avaktivera multival" - units: "Enheter" - validation_failure_date: "inte är ett giltigt datum" - validation_failure_integer: "är inte ett giltigt heltal" diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml deleted file mode 100644 index 7b849900..00000000 --- a/config/locales/crowdin/tr.yml +++ /dev/null @@ -1,49 +0,0 @@ -tr: - button_save_as: "Raporu... şeklinde kaydet" - comments: "Yorum" - cost_reports_title: "Maliyet raporları" - label_cost_report: "Maliyet raporu" - description_drill_down: "Ayrıntıları görüntüle" - description_filter_selection: "Seçim" - description_multi_select: "Çoklu görüntüle" - description_remove_filter: "Süzgeci kaldır" - information_restricted_depending_on_permission: "İzinlerinize bağlı olarak bu sayfa kısıtlı bilgileri içerebilir." - label_click_to_edit: "Düzenlemek için tıklayınız." - label_closed: "kapalı" - label_columns: "Sütunlar" - label_cost_entry_attributes: "Maliyet girişi nitelikleri" - label_days_ago: "son günlerde" - label_entry: "Maliyet girişi" - label_filter_text: "Metin filtrele" - label_filter_value: "Değer" - label_filters: "Filtre" - label_greater: ">" - label_is_not_project_with_subprojects: "değil (alt projeler dahil)" - label_is_project_with_subprojects: "(alt projeler dahil)" - label_work_package_attributes: "Çalışma paketi nitelikleri" - label_less: "<" - label_money: "Nakit değer" - label_month_reporting: "Ay (harcanan)" - label_new_report: "Yeni maliyet raporu" - label_open: "aç" - label_operator: "Operatör" - label_private_report_plural: "Özel maliyet raporları" - label_progress_bar_explanation: "Rapor oluşturuluyor..." - label_public_report_plural: "Genele açık maliyet raporları" - label_really_delete_question: "Bu raporu silmek istediğinizden emin misiniz?" - label_rows: "Satırlar" - label_saving: "Kaydediliyor ..." - label_spent_on_reporting: "Tarih (harcanan)" - label_sum: "Toplam" - label_units: "Birimler" - label_week_reporting: "Hafta (Harcanan)" - label_year_reporting: "Yıl (Harcanan)" - load_query_question: "%{size} tablo hücresi oluşturulacak ve render işlemi biraz zaman alabilir. Yine de render yapmayı denemek istiyor musunuz?" - permission_save_cost_reports: "Genele açık maliyet raporlarını kaydet" - permission_save_private_cost_reports: "Özel maliyet raporlarını kaydet" - project_module_reporting_module: "Maliyet raporları" - text_costs_are_rounded_note: "Gösterilen değerler yuvarlanmıştır. Bütün hesaplamalar yuvarlanmamış değerlere göre yapılır." - toggle_multiselect: "çoklu seçimi etkinleştir/devre dışı bırak" - units: "Birimler" - validation_failure_date: "geçerli bir tarih değil" - validation_failure_integer: "geçerli bir tamsayı değil" diff --git a/config/locales/crowdin/zh-CN.yml b/config/locales/crowdin/zh-CN.yml deleted file mode 100644 index 85aadcec..00000000 --- a/config/locales/crowdin/zh-CN.yml +++ /dev/null @@ -1,49 +0,0 @@ -zh-CN: - button_save_as: "报告另存为..." - comments: "注释" - cost_reports_title: "成本报告" - label_cost_report: "成本报告" - description_drill_down: "显示详情" - description_filter_selection: "选择" - description_multi_select: "显示多选" - description_remove_filter: "删除筛选器" - information_restricted_depending_on_permission: "根据您的权限,此页面可能包含受限的信息。" - label_click_to_edit: "单击此处进行编辑。" - label_closed: "已关闭" - label_columns: "列" - label_cost_entry_attributes: "成本条目属性" - label_days_ago: "在过去几天" - label_entry: "成本条目" - label_filter_text: "筛选器文本" - label_filter_value: "值" - label_filters: "筛选器" - label_greater: ">" - label_is_not_project_with_subprojects: "不是(包含子项目)" - label_is_project_with_subprojects: "是(包含子项目)" - label_work_package_attributes: "工作包属性" - label_less: "<" - label_money: "现金价值" - label_month_reporting: "月(已过)" - label_new_report: "新成本报告" - label_open: "打开" - label_operator: "运算符" - label_private_report_plural: "私人成本报告" - label_progress_bar_explanation: "正在生成报告..." - label_public_report_plural: "公共成本报告" - label_really_delete_question: "是否确定想要删除此报告?" - label_rows: "行" - label_saving: "正在保存..." - label_spent_on_reporting: "日期(已过)" - label_sum: "总计" - label_units: "单位" - label_week_reporting: "周(已过)" - label_year_reporting: "年(已过)" - load_query_question: "报告有 %{size} 个表格单元格,可能需要一些时间渲染。您仍然想要尝试渲染它吗?" - permission_save_cost_reports: "保存公共成本报告" - permission_save_private_cost_reports: "保存私人成本报告" - project_module_reporting_module: "成本报告" - text_costs_are_rounded_note: "显示的值经过四舍五入。所有计算均基于非四舍五入值。" - toggle_multiselect: "激活/取消激活多选" - units: "单位" - validation_failure_date: "不是有效的日期" - validation_failure_integer: "不是有效的整数" diff --git a/config/locales/crowdin/zh-TW.yml b/config/locales/crowdin/zh-TW.yml deleted file mode 100644 index 5dc0d3db..00000000 --- a/config/locales/crowdin/zh-TW.yml +++ /dev/null @@ -1,49 +0,0 @@ -zh-TW: - button_save_as: "將報表另存為..。" - comments: "評論" - cost_reports_title: "成本報告" - label_cost_report: "成本報告" - description_drill_down: "顯示詳細資訊" - description_filter_selection: "選擇" - description_multi_select: "顯示多選" - description_remove_filter: "刪除篩選器" - information_restricted_depending_on_permission: "根據您的許可權, 此頁可能包含受限資訊。" - label_click_to_edit: "按一下此處進行編輯。" - label_closed: "已關閉" - label_columns: "欄位" - label_cost_entry_attributes: "成本項屬性" - label_days_ago: "在最後的日子裡" - label_entry: "成本項" - label_filter_text: "篩選文本" - label_filter_value: "值" - label_filters: "篩選器" - label_greater: ">" - label_is_not_project_with_subprojects: "不是 (包括子專案)" - label_is_project_with_subprojects: "是 (包括子專案)" - label_work_package_attributes: "工作包屬性" - label_less: "<" - label_money: "現金價值" - label_month_reporting: "月 (已用)" - label_new_report: "新建成本報表" - label_open: "打開" - label_operator: "操作員" - label_private_report_plural: "私密成本報告" - label_progress_bar_explanation: "正在生成報表..。" - label_public_report_plural: "公開成本報告" - label_really_delete_question: "確定要刪除此報告嗎?" - label_rows: "行" - label_saving: "儲存中..." - label_spent_on_reporting: "日期 (已用)" - label_sum: "總和" - label_units: "單位" - label_week_reporting: "星期 (已用)" - label_year_reporting: "年 (已用)" - load_query_question: "報表將具有 %{size} 表儲存格, 並且可能需要一些時間來呈現。是否仍要嘗試呈現?" - permission_save_cost_reports: "保存公開成本報告" - permission_save_private_cost_reports: "保存私密成本報告" - project_module_reporting_module: "成本報告" - text_costs_are_rounded_note: "顯示的值被舍入。所有計算都基於非舍入值。" - toggle_multiselect: "啟動/停用多選" - units: "單位" - validation_failure_date: "不是有效日期" - validation_failure_integer: "不是有效的整數" diff --git a/config/locales/en.yml b/config/locales/en.yml deleted file mode 100644 index 0e61e3d0..00000000 --- a/config/locales/en.yml +++ /dev/null @@ -1,77 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - ---- -en: - button_save_as: "Save report as..." - - comments: "Comment" - cost_reports_title: "Cost reports" - label_cost_report: "Cost report" - - description_drill_down: "Show details" - description_filter_selection: "Selection" - description_multi_select: "Show multiselect" - description_remove_filter: "Remove filter" - - information_restricted_depending_on_permission: "Depending on your permissions this page might contain restricted information." - - label_click_to_edit: "Click to edit." - label_closed: "closed" - label_columns: "Columns" - label_cost_entry_attributes: "Cost entry attributes" - label_days_ago: "during the last days" - label_entry: "Cost entry" - label_filter_text: "Filter text" - label_filter_value: "Value" - label_filters: "Filter" - label_greater: ">" - label_is_not_project_with_subprojects: "is not (includes subprojects)" - label_is_project_with_subprojects: "is (includes subprojects)" - label_work_package_attributes: "Work package attributes" - label_less: "<" - label_money: "Cash value" - label_month_reporting: "Month (Spent)" - label_new_report: "New cost report" - label_open: "open" - label_operator: "Operator" - label_private_report_plural: "Private cost reports" - label_progress_bar_explanation: "Generating report..." - label_public_report_plural: "Public cost reports" - label_really_delete_question: "Are you sure you want to delete this report?" - label_rows: "Rows" - label_saving: "Saving ..." - label_spent_on_reporting: "Date (Spent)" - label_sum: "Sum" - label_units: "Units" - label_week_reporting: "Week (Spent)" - label_year_reporting: "Year (Spent)" - load_query_question: "Report will have %{size} table cells and may take some time to render. Do you still want to try rendering it?" - - permission_save_cost_reports: "Save public cost reports" - permission_save_private_cost_reports: "Save private cost reports" - project_module_reporting_module: "Cost reports" - - text_costs_are_rounded_note: "Displayed values are rounded. All calculations are based on the non-rounded values." - toggle_multiselect: "activate/deactivate multiselect" - - units: "Units" - - validation_failure_date: "is not a valid date" - validation_failure_integer: "is not a valid integer" diff --git a/config/routes.rb b/config/routes.rb deleted file mode 100644 index ae55ffe3..00000000 --- a/config/routes.rb +++ /dev/null @@ -1,48 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -OpenProject::Application.routes.draw do - scope 'projects/:project_id' do - resources :cost_reports, except: :create do - collection do - match :index, via: [:get, :post] - end - - member do - post :update - post :rename - end - end - end - - resources :cost_reports, except: :create do - collection do - match :index, via: [:get, :post] - post :save_as, action: :create - get :drill_down - match :available_values, via: [:get, :post] - get :display_report_list - end - - member do - post :update - post :rename - end - end -end diff --git a/db/migrate/20180323130704_to_v710_aggregated_reporting_migrations.rb b/db/migrate/20180323130704_to_v710_aggregated_reporting_migrations.rb deleted file mode 100644 index e3b0b925..00000000 --- a/db/migrate/20180323130704_to_v710_aggregated_reporting_migrations.rb +++ /dev/null @@ -1,54 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require Rails.root.join("db", "migrate", "migration_utils", "migration_squasher").to_s -# This migration aggregates the migrations detailed in MIGRATION_FILES -class ToV710AggregatedReportingMigrations < ActiveRecord::Migration[5.1] - MIGRATION_FILES = <<-MIGRATIONS - 20110215143061_aggregated_reporting_migrations.rb - 20130612104243_reporting_migrate_serialized_yaml.rb - 20130925090243_cost_reports_migration.rb - MIGRATIONS - - def up - Migration::MigrationSquasher.squash(migrations) do - create_table "cost_queries", id: :integer do |t| - t.integer "user_id", :null => false - t.integer "project_id" - t.string "name", :null => false - t.boolean "is_public", :default => false, :null => false - t.datetime "created_on", :null => false - t.datetime "updated_on", :null => false - t.string "serialized", :limit => 2000, :null => false - end - end - end - - def down - drop_table "cost_queries" - end - - private - - def migrations - MIGRATION_FILES.split.map do |m| - m.gsub(/_.*\z/, '') - end - end -end diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md deleted file mode 100644 index f995a624..00000000 --- a/doc/CHANGELOG.md +++ /dev/null @@ -1,72 +0,0 @@ - - -# Changelog - -## 3.0.8 - -* `#7905` custom field not removed from cost report after delete -* `#5191` Public Release Reporting Plugin -* `#4024` Fix: Subpages have no unique page titles - -## 4.0.0 - -* `#3216` Fix: Reporting creates 500 when a CustomField with content type version or user exists -* `#4024` Subpages have no unique page titles - -## 4.0.0.pre9 - -* Adaptations for new icon font -* added icon for new project menu - -## 4.0.0.pre8 - -* `#2731` Migrated serialized yaml from syck to psych - -## 4.0.0.pre7 - -* `#2449` Squash old migrations -* `#2517` XSS: unescaped fields in cost report view (cost log comment, work package title) - -## 4.0.0.pre6 - -* New core version dependency. - -## 4.0.0.pre5 - -* Rename IssueCategory to Category - -## 4.0.0.pre4 - -* `#2061` Migrate to new data model. - -## 4.0.0.pre3 - -Adapt to OpenProject core - -## 4.0.0.pre2 - -* Fixed grouping by authors -* Added reporting permissions -* Translation fixes - -## 4.0.0.pre1 - -* First release of the Rails 3 version diff --git a/doc/COPYRIGHT.md b/doc/COPYRIGHT.md deleted file mode 100644 index de7d8de8..00000000 --- a/doc/COPYRIGHT.md +++ /dev/null @@ -1,18 +0,0 @@ -OpenProject Reporting Plugin - -An OpenProject plugin to create cost reports - -Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 3. - -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. diff --git a/doc/COPYRIGHT_short.md b/doc/COPYRIGHT_short.md deleted file mode 100644 index 812d9ca4..00000000 --- a/doc/COPYRIGHT_short.md +++ /dev/null @@ -1,16 +0,0 @@ -OpenProject Reporting Plugin - -Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 3. - -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. diff --git a/doc/GPL.txt b/doc/GPL.txt deleted file mode 100644 index 94a9ed02..00000000 --- a/doc/GPL.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 3 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, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/features/step_definitions/disabled_scenarios.rb b/features/step_definitions/disabled_scenarios.rb deleted file mode 100644 index e9b59c08..00000000 --- a/features/step_definitions/disabled_scenarios.rb +++ /dev/null @@ -1,21 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -ScenarioDisabler.disable(feature: "Tracking Time", scenario: "Adding a time entry") -ScenarioDisabler.disable(feature: "Tracking Time", scenario: "Editing a time entry") diff --git a/lib/open_project/reporting.rb b/lib/open_project/reporting.rb deleted file mode 100644 index 7813655f..00000000 --- a/lib/open_project/reporting.rb +++ /dev/null @@ -1,24 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject - module Reporting - require "open_project/reporting/engine" - end -end diff --git a/lib/open_project/reporting/default_data.rb b/lib/open_project/reporting/default_data.rb deleted file mode 100644 index be7cbe4f..00000000 --- a/lib/open_project/reporting/default_data.rb +++ /dev/null @@ -1,32 +0,0 @@ -module OpenProject - module Reporting - module DefaultData - module_function - - def load! - restrict_project_admin_permissions! - end - - ## - # The Project Admin role is assigned all possible permission in - # the core's `roles.rb` seed. Here we remove those permissions - # which should not be assigned by default. - def restrict_project_admin_permissions! - role = project_admin_role or raise 'Project admin role not found' - - role.remove_permission! *restricted_project_admin_permissions - end - - def project_admin_role - Role.find_by name: I18n.t(:default_role_project_admin) - end - - def restricted_project_admin_permissions - [ - :save_cost_reports, - :save_private_cost_reports - ] - end - end - end -end diff --git a/lib/open_project/reporting/engine.rb b/lib/open_project/reporting/engine.rb deleted file mode 100644 index 7d9489eb..00000000 --- a/lib/open_project/reporting/engine.rb +++ /dev/null @@ -1,111 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting - class Engine < ::Rails::Engine - engine_name :openproject_reporting - - include OpenProject::Plugins::ActsAsOpEngine - - register 'openproject-reporting', - author_url: 'http://finn.de', - requires_openproject: '>= 4.0.0' do - - view_actions = [:index, :show, :drill_down, :available_values, :display_report_list] - edit_actions = [:create, :update, :rename, :destroy] - - #register reporting_module including permissions - project_module :reporting_module do - permission :save_cost_reports, {cost_reports: edit_actions} - permission :save_private_cost_reports, {cost_reports: edit_actions} - end - - #register additional permissions for viewing time and cost entries through the CostReportsController - view_actions.each do |action| - Redmine::AccessControl.permission(:view_time_entries).actions << "cost_reports/#{action}" - Redmine::AccessControl.permission(:view_own_time_entries).actions << "cost_reports/#{action}" - Redmine::AccessControl.permission(:view_cost_entries).actions << "cost_reports/#{action}" - Redmine::AccessControl.permission(:view_own_cost_entries).actions << "cost_reports/#{action}" - end - - #menu extensions - menu :top_menu, :cost_reports_global, {controller: '/cost_reports', action: 'index', project_id: nil}, - caption: :cost_reports_title, - if: Proc.new { - (User.current.logged? || !Setting.login_required?) && - ( - User.current.allowed_to?(:view_time_entries, nil, global: true) || - User.current.allowed_to?(:view_own_time_entries, nil, global: true) || - User.current.allowed_to?(:view_cost_entries, nil, global: true) || - User.current.allowed_to?(:view_own_cost_entries, nil, global: true) - ) - } - - menu :project_menu, :cost_reports, - {controller: '/cost_reports', action: 'index'}, - param: :project_id, - after: :time_entries, - caption: :cost_reports_title, - if: Proc.new { |project| project.module_enabled?(:reporting_module) }, - icon: 'icon2 icon-cost-reports' - - # Cost reports should remove the default time entries menu item - hide_menu_item :project_menu, - :time_entries, - hide_if: -> (project) { project.module_enabled?(:reporting_module) } - - hide_menu_item :top_menu, - :time_sheet - end - - initializer "reporting.register_hooks" do - # don't use require_dependency to not reload hooks in development mode - require 'open_project/reporting/hooks' - end - - initializer 'reporting.precompile_assets' do - Rails.application.config.assets.precompile += %w( - reporting_engine/reporting_engine.css - reporting_engine/reporting_engine.js - ) - - # Without this, tablesorter's assets are not found. - # This should actually be done by rails itself when one adds the gem to the gemspec. - Rails.application.config.assets.paths << Gem.loaded_specs['jquery-tablesorter'].full_gem_path + '/vendor/assets/javascripts' - end - - config.to_prepare do - require_dependency 'report/walker' - require_dependency 'report/transformer' - require_dependency 'widget/entry_table' - require_dependency 'widget/settings_patch' - require_dependency 'cost_query/group_by' - end - - assets %w(reporting/reporting.css - reporting/reporting.js) - - patches [:CostlogController, - :TimelogController, - :CustomFieldsController, - :'OpenProject::Configuration'] - patch_with_namespace :BasicData, :RoleSeeder - patch_with_namespace :BasicData, :SettingSeeder - end -end diff --git a/lib/open_project/reporting/hooks.rb b/lib/open_project/reporting/hooks.rb deleted file mode 100644 index 01f10b9e..00000000 --- a/lib/open_project/reporting/hooks.rb +++ /dev/null @@ -1,21 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting::Hooks -end diff --git a/lib/open_project/reporting/patches.rb b/lib/open_project/reporting/patches.rb deleted file mode 100644 index a7a88113..00000000 --- a/lib/open_project/reporting/patches.rb +++ /dev/null @@ -1,21 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting::Patches -end diff --git a/lib/open_project/reporting/patches/costlog_controller_patch.rb b/lib/open_project/reporting/patches/costlog_controller_patch.rb deleted file mode 100644 index 9aba6db4..00000000 --- a/lib/open_project/reporting/patches/costlog_controller_patch.rb +++ /dev/null @@ -1,85 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require_dependency 'costlog_controller' - -module OpenProject::Reporting::Patches - module CostlogControllerPatch - def self.included(base) # :nodoc: - base.prepend InstanceMethods - end - - module InstanceMethods - ## - # @Override - # This is for cost reporting - def redirect_to(*args, &block) - if args.first == :back and args.size == 1 and request.referer =~ /cost_reports/ - super(controller: '/cost_reports', action: :index) - else - super(*args, &block) - end - end - - def index - # we handle single project reporting currently - if @project.nil? || !@project.module_enabled?(:reporting_module) - return super - end - filters = {operators: {}, values: {}} - - if @work_package - if @work_package.respond_to?("lft") - work_package_ids = @work_package.self_and_descendants.pluck(:id) - else - work_package_ids = [@work_package.id] - end - - filters[:operators][:work_package_id] = "=" - filters[:values][:work_package_id] = work_package_ids - end - - filters[:operators][:project_id] = "=" - filters[:values][:project_id] = [@project.id.to_s] - - respond_to do |format| - format.html { - session[CostQuery.name.underscore.to_sym] = { filters: filters, groups: {rows: [], columns: []} } - - if @cost_type - redirect_to controller: "/cost_reports", action: "index", project_id: @project, unit: @cost_type.id - else - redirect_to controller: "/cost_reports", action: "index", project_id: @project - end - return - } - format.all { - super - } - end - end - - def find_optional_project - super - deny_access unless User.current.allowed_to?(:view_cost_entries, @project, global: true) || - User.current.allowed_to?(:view_own_cost_entries, @project, global: true) - end - end - end -end diff --git a/lib/open_project/reporting/patches/custom_fields_controller_patch.rb b/lib/open_project/reporting/patches/custom_fields_controller_patch.rb deleted file mode 100644 index 4a417eb2..00000000 --- a/lib/open_project/reporting/patches/custom_fields_controller_patch.rb +++ /dev/null @@ -1,84 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require_dependency 'costlog_controller' - -module OpenProject::Reporting::Patches - module CustomFieldsControllerPatch - def self.included(base) # :nodoc: - base.prepend InstanceMethods - end - - module InstanceMethods - def destroy - id = @custom_field.id - begin - reports = CostQuery.where("serialized LIKE '%CustomField#{id}%'") - - remove_custom_field_from_cost_report(reports, id) - remove_custom_field_from_session(id) - rescue => e - Rails.logger.error "Failed to remove custom_field #{id} from custom queries. " \ - "#{e.class}: #{e.message}" - ensure - super - end - end - - private - - def remove_custom_field_from_cost_report(affected_reports, id) - custom_field_name = "CustomField#{id}" - - affected_reports.each do |report| - filters = reject_from_query_properties(report, :filters, custom_field_name) - group_bys = reject_from_query_properties(report, :group_bys, custom_field_name) - updated_report = build_query(report.engine, filters, group_bys) - report.migrate(updated_report) - report.save! - end - end - - def reject_from_query_properties(report, property, custom_field_name) - report.serialized[property].reject { |f| f[0] == custom_field_name } - end - - def build_query(report_engine, filters, groups = {}) - query = report_engine.deserialize({ filters: filters, group_bys: groups }) - query.serialize - query - end - - def remove_custom_field_from_session(id) - custom_field_name = "custom_field#{id}".to_sym - report_engine_name = CostQuery.name.underscore.to_sym - cookie = session[report_engine_name] - - if cookie - cookie[:filters][:operators].delete(custom_field_name) - cookie[:filters][:values].delete(custom_field_name) - cookie[:groups][:rows].delete(custom_field_name.to_s) - cookie[:groups][:columns].delete(custom_field_name.to_s) - - session[report_engine_name] = cookie - end - end - end - end -end diff --git a/lib/open_project/reporting/patches/open_project/configuration_patch.rb b/lib/open_project/reporting/patches/open_project/configuration_patch.rb deleted file mode 100644 index 4497c3a6..00000000 --- a/lib/open_project/reporting/patches/open_project/configuration_patch.rb +++ /dev/null @@ -1,47 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - - -require_dependency 'open_project/configuration' - -module OpenProject::Reporting::Patches - module OpenProject::ConfigurationPatch - def self.included(base) - base.class_eval do - extend ModuleMethods - - @defaults['cost_reporting_cache_filter_classes'] = true - - if config_loaded_before_patch? - @config['cost_reporting_cache_filter_classes'] = true - end - end - end - - module ModuleMethods - def config_loaded_before_patch? - @config.present? && !@config.has_key?('cost_reporting_cache_filter_classes') - end - - def cost_reporting_cache_filter_classes - @config['cost_reporting_cache_filter_classes'] - end - end - end -end diff --git a/lib/open_project/reporting/patches/role_seeder_patch.rb b/lib/open_project/reporting/patches/role_seeder_patch.rb deleted file mode 100644 index 4d6ea6bc..00000000 --- a/lib/open_project/reporting/patches/role_seeder_patch.rb +++ /dev/null @@ -1,32 +0,0 @@ -#-- copyright -# OpenProject Costs Plugin -# -# Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting::Patches::RoleSeederPatch - def self.included(base) # :nodoc: - base.prepend InstanceMethods - end - - module InstanceMethods - def seed_data! - super.tap do |_| - OpenProject::Reporting::DefaultData.load! - end - end - end -end diff --git a/lib/open_project/reporting/patches/setting_seeder_patch.rb b/lib/open_project/reporting/patches/setting_seeder_patch.rb deleted file mode 100644 index 09e19b5e..00000000 --- a/lib/open_project/reporting/patches/setting_seeder_patch.rb +++ /dev/null @@ -1,36 +0,0 @@ -#-- copyright -# OpenProject Costs Plugin -# -# Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting::Patches::SettingSeederPatch - def self.included(base) # :nodoc: - base.prepend InstanceMethods - end - - module InstanceMethods - def data - original_data = super - - unless original_data['default_projects_modules'].include? 'reporting_module' - original_data['default_projects_modules'] << 'reporting_module' - end - - original_data - end - end -end diff --git a/lib/open_project/reporting/patches/timelog_controller_patch.rb b/lib/open_project/reporting/patches/timelog_controller_patch.rb deleted file mode 100644 index aeb18c9f..00000000 --- a/lib/open_project/reporting/patches/timelog_controller_patch.rb +++ /dev/null @@ -1,85 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require_dependency 'timelog_controller' - -module OpenProject::Reporting::Patches - module TimelogControllerPatch - def self.included(base) # :nodoc: - base.prepend InstanceMethods - end - - module InstanceMethods - ## - # @Override - # This is for cost reporting - def redirect_to(*args, &block) - if args.first == :back and args.size == 1 and request.referer =~ /cost_reports/ - super(controller: '/cost_reports', action: :index) - else - super(*args, &block) - end - end - - def index - # we handle single project reporting currently - if @project.nil? || !@project.module_enabled?(:reporting_module) - return super - end - filters = {operators: {}, values: {}} - - if @issue - if @issue.respond_to?("lft") - work_package_ids = @issue.self_and_descendants.pluck(:id) - else - work_package_ids = [@issue.id.to_s] - end - - filters[:operators][:work_package_id] = "=" - filters[:values][:work_package_id] = [work_package_ids] - end - - filters[:operators][:project_id] = "=" - filters[:values][:project_id] = [@project.id.to_s] - - respond_to do |format| - format.html { - session[::CostQuery.name.underscore.to_sym] = { filters: filters, groups: {rows: [], columns: []} } - - redirect_to controller: "/cost_reports", action: "index", project_id: @project, unit: -1 - } - format.all { - super - } - end - end - - def find_optional_project - if !params[:work_package_id].blank? - @issue = WorkPackage.find(params[:work_package_id]) - @project = @issue.project - elsif !params[:project_id].blank? - @project = Project.find(params[:project_id]) - end - deny_access unless User.current.allowed_to?(:view_time_entries, @project, global: true) || - User.current.allowed_to?(:view_own_time_entries, @project, global: true) - end - end - end -end diff --git a/lib/open_project/reporting/version.rb b/lib/open_project/reporting/version.rb deleted file mode 100644 index 7df7195c..00000000 --- a/lib/open_project/reporting/version.rb +++ /dev/null @@ -1,24 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject - module Reporting - VERSION = "8.2.0" - end -end diff --git a/lib/openproject-reporting.rb b/lib/openproject-reporting.rb deleted file mode 100644 index 5fbab2db..00000000 --- a/lib/openproject-reporting.rb +++ /dev/null @@ -1,20 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require 'open_project/reporting' diff --git a/lib/widget/cost_types.rb b/lib/widget/cost_types.rb deleted file mode 100644 index a049d15d..00000000 --- a/lib/widget/cost_types.rb +++ /dev/null @@ -1,46 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class Widget::CostTypes < Widget::Base - def render_with_options(options, &block) - @cost_types = options.delete(:cost_types) - @selected_type_id = options.delete(:selected_type_id) - - super(options, &block) - end - - def render - write contents - end - - def contents - content_tag :div do - available_cost_type_tabs(@subject).sort_by { |id, _| id }.map do |id, label| - content_tag :div, class: "form--field -trailing-label" do - types = label_tag "unit_#{id}", h(label), class: "form--label" - types += content_tag :span, class: "form--field-container" do - content_tag :span, class: "form--radio-button-container" do - radio_button_tag('unit', id, id == @selected_type_id, class: "form--radio-button") - end - end - end - end.join('').html_safe - end - end -end diff --git a/lib/widget/entry_table.rb b/lib/widget/entry_table.rb deleted file mode 100644 index fa72dab4..00000000 --- a/lib/widget/entry_table.rb +++ /dev/null @@ -1,165 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -class ::Widget::Table::EntryTable < ::Widget::Table - FIELDS = [:spent_on, :user_id, :activity_id, :work_package_id, :comments, :project_id] - - detailed_table self - - def render - content = content_tag :div, class: 'generic-table--container -with-footer' do - content_tag :div, class: 'generic-table--results-container' do - table = content_tag :table, 'interactive-table' => true, - class: 'generic-table', - id: 'sortable-table' do - concat colgroup - concat head - concat foot - concat body - end - table - end - end - write content - end - - def colgroup - content_tag :colgroup do - FIELDS.each do - concat content_tag(:col, 'highlight-col' => true) {} - end - concat content_tag(:col, 'highlight-col' => true) {} - concat content_tag(:col, 'highlight-col' => true) {} - concat content_tag(:col) {} - end - end - - def head - content_tag :thead do - content_tag :tr do - FIELDS.map do |field| - concat content_tag(:th) { - content_tag(:div, class: 'generic-table--sort-header-outer') do - content_tag(:div, class: 'generic-table--sort-header') do - content_tag(:span, label_for(field)) - end - end - } - end - concat content_tag(:th) { - content_tag(:div, class: 'generic-table--sort-header-outer') do - content_tag(:div, class: 'generic-table--sort-header') do - content_tag(:span, cost_type.try(:unit_plural) || l(:units)) - end - end - } - concat content_tag(:th) { - content_tag(:div, class: 'generic-table--sort-header-outer') do - content_tag(:div, class: 'generic-table--sort-header') do - content_tag(:span, CostEntry.human_attribute_name(:costs)) - end - end - } - hit = false - @subject.each_direct_result do |result| - next if hit - if entry_for(result).editable_by? User.current - concat content_tag(:th, class: 'unsortable') { - content_tag(:div, '', class: 'generic-table--empty-header') - } - hit = true - end - end - end - end - end - - def foot - content_tag :tfoot do - content_tag :tr do - if show_result(@subject, 0) != show_result(@subject) - concat content_tag(:td, '', colspan: FIELDS.size) - concat content_tag(:td) { - concat content_tag(:div, - show_result(@subject), - class: 'inner generic-table--footer-outer') - } - concat content_tag(:td) { - concat content_tag(:div, - show_result(@subject, 0), - class: 'result generic-table--footer-outer') - } - else - concat content_tag(:td, '', colspan: FIELDS.size + 1) - concat content_tag(:td) { - concat content_tag(:div, - show_result(@subject), - class: 'result generic-table--footer-outer') - } - end - concat content_tag(:th, '', class: 'unsortable') - end - end - end - - def body - content_tag :tbody do - rows = ''.html_safe - @subject.each_direct_result do |result| - rows << (content_tag(:tr) do - ''.html_safe - FIELDS.each do |field| - concat content_tag(:td, show_field(field, result.fields[field.to_s]).html_safe, - :'raw-data' => raw_field(field, result.fields[field.to_s]), - class: 'left') - end - concat content_tag :td, show_result(result, result.fields['cost_type_id'].to_i).html_safe, - class: 'units right', - :'raw-data' => result.units - concat content_tag :td, - (show_result(result, 0)).html_safe, - class: 'currency right', - :'raw-data' => result.real_costs - concat content_tag :td, icons(result) - end) - end - rows - end - end - - def icons(result) - icons = '' - with_project(result.fields['project_id']) do - if entry_for(result).editable_by? User.current - icons = link_to(icon_wrapper('icon-context icon-edit', l(:button_edit)), - action_for(result, action: 'edit'), - class: 'no-decoration-on-hover', - title: l(:button_edit)) - icons << link_to(icon_wrapper('icon-context icon-delete', l(:button_delete)), - (action_for(result, action: 'destroy') - .reverse_merge(authenticity_token: form_authenticity_token)), - data: { confirm: l(:text_are_you_sure) }, - method: :delete, - class: 'no-decoration-on-hover', - title: l(:button_delete)) - end - end - icons - end -end diff --git a/lib/widget/settings_patch.rb b/lib/widget/settings_patch.rb deleted file mode 100644 index 66418333..00000000 --- a/lib/widget/settings_patch.rb +++ /dev/null @@ -1,39 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -#explicitly require what will be patched to be loaded from the ReportingEngine -require_dependency 'widget/settings' -class Widget::Settings < Widget::Base - @@settings_to_render.insert -2, :cost_types - - def render_cost_types_settings - render_widget Widget::Settings::Fieldset, @subject, { type: "units" } do - render_widget Widget::CostTypes, - @cost_types, - selected_type_id: @selected_type_id - end - end - - def render_with_options(options, &block) - @cost_types = options.delete(:cost_types) - @selected_type_id = options.delete(:selected_type_id) - - super(options, &block) - end -end diff --git a/openproject-reporting.gemspec b/openproject-reporting.gemspec deleted file mode 100644 index 0337c14e..00000000 --- a/openproject-reporting.gemspec +++ /dev/null @@ -1,25 +0,0 @@ -$:.push File.expand_path("../lib", __FILE__) - -# Maintain your gem's version: -require "open_project/reporting/version" - -# Describe your gem and declare its dependencies: -Gem::Specification.new do |s| - s.name = "openproject-reporting" - s.version = OpenProject::Reporting::VERSION - s.authors = "OpenProject GmbH" - s.email = "info@openproject.com" - s.homepage = "https://community.openproject.org/projects/plugin-reporting" - s.summary = "OpenProject Reporting" - s.description = "This plugin allows creating custom cost reports with filtering and grouping created by the OpenProject Costs plugin" - - s.files = Dir["{app,config,db,lib,doc}/**/*", "README.md"] - s.test_files = Dir["spec/**/*"] - - s.add_dependency "reporting_engine", ">= 1.1.0" - s.add_dependency "openproject-costs", "= #{OpenProject::Reporting::VERSION}" - - s.add_dependency 'jquery-tablesorter', '~> 1.25.5' - - s.add_development_dependency "factory_girl_rails", "~> 4.0" -end diff --git a/spec/controllers/cost_reports_controller_spec.rb b/spec/controllers/cost_reports_controller_spec.rb deleted file mode 100644 index 45b1aadd..00000000 --- a/spec/controllers/cost_reports_controller_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') - -describe CostReportsController, type: :controller do - include OpenProject::Reporting::PluginSpecHelper - - let(:user) { FactoryBot.build(:user) } - let(:project) { FactoryBot.build(:valid_project) } - - describe "GET show" do - before(:each) do - is_member project, user, [:view_cost_entries] - allow(User).to receive(:current).and_return(user) - end - - describe "WHEN providing invalid units - WHEN having the view_cost_entries permission" do - before do - get :show, params: { id: 1, unit: -1 } - end - - it "should respond with a 404 error" do - expect(response.code).to eql("404") - end - end - end -end diff --git a/spec/controllers/custom_fields_controller_spec.rb b/spec/controllers/custom_fields_controller_spec.rb deleted file mode 100644 index 054219b8..00000000 --- a/spec/controllers/custom_fields_controller_spec.rb +++ /dev/null @@ -1,147 +0,0 @@ -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2014 the OpenProject Foundation (OPF) -# -# 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 doc/COPYRIGHT.rdoc for more details. -#++ - -require 'spec_helper' - -describe CustomFieldsController do - let!(:custom_field) { FactoryBot.create(:work_package_custom_field) } - let!(:custom_field_permanent) { FactoryBot.create(:work_package_custom_field) } - let(:custom_field_name) { "CustomField#{custom_field.id}" } - let(:custom_field_permanent_name) { "CustomField#{custom_field_permanent.id}" } - let(:cost_query) { FactoryBot.build(:cost_query) } - - before do - allow(@controller).to receive(:authorize) - allow(@controller).to receive(:check_if_login_required) - allow(@controller).to receive(:require_admin) - - CostQuery::Filter::CustomFieldEntries.reset! - CostQuery::Filter::CustomFieldEntries.all - - CostQuery::GroupBy::CustomFieldEntries.reset! - CostQuery::GroupBy::CustomFieldEntries.all - end - - describe '#destroy' do - shared_context 'remove custom field' do - before do - cost_query.filter(custom_field_permanent_name, { operator: '=', values: [] }) - cost_query.group_by(custom_field_permanent_name) - cost_query.save! - - delete :destroy, params: { id: custom_field.id } - end - end - - shared_examples_for 'custom field is removed from cost query' do - include_context 'remove custom field' - - shared_examples_for 'custom field removed' do - it { expect(subject).not_to include(name) } - end - - shared_examples_for 'custom field exists' do - it { expect(subject).to include(name) } - end - - describe 'custom field is removed from cost query filter' do - subject { CostQuery.find(cost_query.id).filters.collect(&:class).collect(&:name) } - - it_behaves_like 'custom field removed' do - let(:name) { "CostQuery::Filter::#{custom_field_name}" } - end - end - - describe 'custom field is removed from cost query group bys' do - subject { CostQuery.find(cost_query.id).group_bys.collect(&:class).collect(&:name) } - - it_behaves_like 'custom field removed' do - let(:name) { "CostQuery::GroupBy::#{custom_field_name}" } - end - end - - describe 'permanent custom field still exists in cost query filter' do - subject { cost_query.reload.filters.collect(&:class).collect(&:name) } - - it_behaves_like 'custom field exists' do - let(:name) { "CostQuery::Filter::#{custom_field_permanent_name}" } - end - end - - describe 'permanent custom field still exists in cost query group by' do - subject { cost_query.reload.group_bys.collect(&:class).collect(&:name) } - - it_behaves_like 'custom field exists' do - let(:name) { "CostQuery::GroupBy::#{custom_field_permanent_name}" } - end - end - end - - context 'with custom field filter set' do - before do - cost_query.filter(custom_field_name, { operator: '=', values: [] }) - end - - it_behaves_like 'custom field is removed from cost query' - end - - context 'with custom field group by set' do - before do - cost_query.group_by(custom_field_name) - end - - it_behaves_like 'custom field is removed from cost query' - end - - context 'session' do - let(:engine_name) { CostQuery.name.underscore.to_sym } - let(:key) { :"custom_field#{custom_field.id}" } - let(:query) { { filters: - { - operators: { user_id: "=", key => "=" }, - values: { user_id: ["96"], key => "" } - }, - groups: { rows: [key.to_s], columns: [key.to_s] } - } - } - before { session[engine_name] = query } - - describe 'does not contain custom field reference' do - include_context 'remove custom field' - - it { expect(session[engine_name][:filters][:operators][key]).to be_nil } - - it { expect(session[engine_name][:filters][:values][key]).to be_nil } - - it { expect(session[engine_name][:groups][:rows]).not_to include(key.to_s) } - - it { expect(session[engine_name][:groups][:columns]).not_to include(key.to_s) } - end - end - end -end diff --git a/spec/disabled_specs.rb b/spec/disabled_specs.rb deleted file mode 100644 index 07ba582a..00000000 --- a/spec/disabled_specs.rb +++ /dev/null @@ -1,27 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require 'rspec/example_disabler' - -RSpec::ExampleDisabler.disable_example('Top menu items as a user with permissions displays all options', 'plugin openproject-reporting removes the menu item') -RSpec::ExampleDisabler.disable_example('Top menu items as an admin visits the time sheet page', 'plugin openproject-reporting removes the menu item') -RSpec::ExampleDisabler.disable_example('Top menu items as an admin displays all items', 'plugin openproject-reporting removes the menu item') -RSpec::ExampleDisabler.disable_example('Top menu items Modules as an admin visits the time sheet page', 'plugin openproject-reporting removes the menu item') -RSpec::ExampleDisabler.disable_example('Top menu items Modules as an admin displays all items', 'plugin openproject-reporting removes the menu item') -RSpec::ExampleDisabler.disable_example('Top menu items Modules as a user with permissions displays all options', 'plugin openproject-reporting removes the menu item') diff --git a/spec/factories/cost_query_factory.rb b/spec/factories/cost_query_factory.rb deleted file mode 100644 index 5441da75..00000000 --- a/spec/factories/cost_query_factory.rb +++ /dev/null @@ -1,32 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -FactoryBot.define do - factory :cost_query do - association :user, factory: :user - association :project, factory: :project - sequence(:name) { |n| "Cost Query #{n}" } - factory :private_cost_query do - is_public false - end - factory :public_cost_query do - is_public true - end - end -end diff --git a/spec/features/calculations_spec.rb b/spec/features/calculations_spec.rb deleted file mode 100644 index dfe7b5e1..00000000 --- a/spec/features/calculations_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'spec_helper' - -describe 'Cost report calculations', type: :feature, js: true do - let(:project) { FactoryBot.create :project } - let(:user) { FactoryBot.create :admin } - - let(:work_package) { FactoryBot.create :work_package, project: project } - let!(:hourly_rate1) { FactoryBot.create :default_hourly_rate, user: user, rate: 1.00, valid_from: 1.year.ago } - let!(:hourly_rate2) { FactoryBot.create :default_hourly_rate, user: user, rate: 5.00, valid_from: 2.years.ago } - let!(:hourly_rate3) { FactoryBot.create :default_hourly_rate, user: user, rate: 10.00, valid_from: 3.years.ago } - - let!(:time_entry1) { - FactoryBot.create :time_entry, - spent_on: 6.months.ago, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - let!(:time_entry2) { - FactoryBot.create :time_entry, - spent_on: 18.months.ago, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - let!(:time_entry3) { - FactoryBot.create :time_entry, - spent_on: 30.months.ago, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - - before do - login_as(user) - visit '/cost_reports?set_filter=1' - end - - - it 'shows the correct calculations' do - expect(page).to have_text '10.00' # 1 EUR x 10 - expect(page).to have_text '50.00' # 5 EUR x 10 - expect(page).to have_text '100.00' # 10 EUR x 10 - expect(page).to have_text '160.00' - end -end \ No newline at end of file diff --git a/spec/features/custom_fields_spec.rb b/spec/features/custom_fields_spec.rb deleted file mode 100644 index ae7edb3e..00000000 --- a/spec/features/custom_fields_spec.rb +++ /dev/null @@ -1,231 +0,0 @@ -#-- copyright -# OpenProject Costs Plugin -# -# Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require 'spec_helper' - -describe 'Custom fields reporting', type: :feature, js: true do - let(:type) { FactoryBot.create :type } - let(:project) { FactoryBot.create :project, types: [type] } - - let(:user) { FactoryBot.create :admin } - - let(:work_package) { - FactoryBot.create :work_package, - project: project, - custom_values: initial_custom_values - } - - let!(:time_entry1) { - FactoryBot.create :time_entry, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - - let!(:time_entry2) { - FactoryBot.create :time_entry, - user: user, - work_package: work_package, - project: project, - hours: 2.50 - } - - - def custom_value_for(cf, str) - cf.custom_options.find { |co| co.value == str }.try(:id) - end - - context 'with multi value cf' do - let!(:custom_field) do - FactoryBot.create( - :list_wp_custom_field, - name: "List CF", - multi_value: true, - types: [type], - projects: [project], - possible_values: ['First option', 'Second option'] - ) - end - - let(:initial_custom_values) { { custom_field.id => custom_value_for(custom_field, 'First option') } } - let(:cf_id) { "custom_field#{custom_field.id}" } - - before do - login_as(user) - visit '/cost_reports' - end - - it 'filters by the multi CF' do - expect(page).to have_selector('#add_filter_select option', text: 'List CF') - select 'List CF', from: 'add_filter_select' - - # Adds filter to page - expect(page).to have_selector("label##{cf_id}") - custom_field_selector = "##{cf_id}_arg_1_val" - select = find(custom_field_selector) - expect(select).to have_selector('option', text: 'First option') - expect(select).to have_selector('option', text: 'Second option') - select.find('option', text: 'First option').select_option - - find('#query-icon-apply-button').click - - # Expect row of work package - within('#result-table') do - expect(page).to have_selector('.top.result', text: '12.50 hours') - end - - # Update filter to other value - select = find(custom_field_selector) - select.find('option', text: 'Second option').select_option - find('#query-icon-apply-button').click - - # Expect empty result table - within('#result-table') do - expect(page).to have_no_selector('.top.result', text: '12.50 hours') - end - expect(page).to have_selector('.generic-table--no-results-title') - end - - it 'groups by the multi CF (Regression #26050)' do - expect(page).to have_selector('#group-by--add-columns') - expect(page).to have_selector('#group-by--add-rows') - - select 'List CF', from: 'group-by--add-columns' - select 'Work package', from: 'group-by--add-rows' - - find('#query-icon-apply-button').click - - # Expect row of work package - within('#result-table') do - expect(page).to have_selector('a.issue', text: "#{work_package.type.to_s} ##{work_package.id}") - expect(page).to have_selector('th.inner', text: 'First option') - expect(page).to have_no_selector('th.inner', text: 'Second option') - - # Only first option should have content for the work package - expect(page).to have_selector('table.report tbody tr', count: 1) - row_elements = page.all('table.report tr.odd th') - - expect(row_elements[0].text).to eq(project.name) - expect(row_elements[1].text).to eq(work_package.to_s) - - row_elements = page.all('table.report tr.odd td') - expect(row_elements[0].text).to eq('12.50 hours') - end - end - - context 'with additional WP with invalid value' do - let!(:custom_field_2) do - FactoryBot.create( - :list_wp_custom_field, - name: "Invalid List CF", - multi_value: true, - types: [type], - projects: [project], - possible_values: ['A', 'B'] - ) - end - - let!(:work_package2) { - FactoryBot.create :work_package, - project: project, - custom_values: { custom_field_2.id => custom_value_for(custom_field_2, 'A')} - } - - let!(:time_entry1) { - FactoryBot.create :time_entry, - user: user, - work_package: work_package2, - project: project, - hours: 10 - } - - before do - CustomValue.find_by(customized_id: work_package2.id).update_columns(value: 'invalid') - work_package2.reload - - login_as(user) - visit '/cost_reports' - end - - it 'groups by the raw values when an invalid value exists' do - expect(work_package2.send("custom_field_#{custom_field_2.id}")).to eq(['invalid not found']) - - expect(page).to have_selector('#group-by--add-columns') - expect(page).to have_selector('#group-by--add-rows') - - select 'Invalid List CF', from: 'group-by--add-columns' - select 'Work package', from: 'group-by--add-rows' - - find('#query-icon-apply-button').click - - # Expect row of work package - within('#result-table') do - expect(page).to have_selector('a.issue', text: "#{work_package.type.to_s} ##{work_package.id}") - expect(page).to have_selector('th.inner', text: '1') - expect(page).to have_no_selector('th.inner', text: 'invalid!') - end - end - end - end - - context 'with text CF' do - let(:custom_field) do - FactoryBot.create( - :text_wp_custom_field, - name: 'Text CF', - types: [type], - projects: [project] - ) - end - let(:initial_custom_values) { { custom_field.id => 'foo' } } - - before do - login_as(user) - visit '/cost_reports' - end - - it 'groups by a text CF' do - expect(page).to have_selector('#group-by--add-columns') - expect(page).to have_selector('#group-by--add-rows') - - select 'Text CF', from: 'group-by--add-columns' - select 'Work package', from: 'group-by--add-rows' - - find('#query-icon-apply-button').click - - # Expect row of work package - within('#result-table') do - expect(page).to have_selector('a.issue', text: "#{work_package.type.to_s} ##{work_package.id}") - expect(page).to have_selector('th.inner', text: 'foo') - expect(page).to have_no_selector('th.inner', text: 'None') - - # Only first option should have content for the work package - expect(page).to have_selector('table.report tbody tr', count: 1) - row_elements = page.all('table.report tr.odd th') - - expect(row_elements[0].text).to eq(project.name) - expect(row_elements[1].text).to eq(work_package.to_s) - - row_elements = page.all('table.report tr.odd td') - expect(row_elements[0].text).to eq('12.50 hours') - end - end - end -end diff --git a/spec/features/filter_spec.rb b/spec/features/filter_spec.rb deleted file mode 100644 index 045fdacc..00000000 --- a/spec/features/filter_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper' - -describe 'Cost report calculations', type: :feature, js: true do - let(:project) { FactoryBot.create :project } - let(:user) { FactoryBot.create :admin } - - before do - login_as(user) - visit cost_reports_path(project) - end - - it 'provides filtering' do - # Then filter "spent_on" should be visible - # And filter "user_id" should be visible - expect(page).to have_selector("#filter_spent_on") - expect(page).to have_selector("#filter_user_id") - - # Remove filter: - # And I click on "Clear" - click_on 'Clear' - # Then filter "spent_on" should not be visible - # And filter "user_id" should not be visible - expect(page).to have_no_selector("#filter_spent_on") - expect(page).to have_no_selector("#filter_user_id") - - # Reload restores the query - # And the user with the login "developer" should be selected for "User Value" - # And "!" should be selected for "User Operator Open this filter with 'ALT' and arrow keys." - visit cost_reports_path(project) - expect(page).to have_selector("#filter_spent_on") - expect(page).to have_selector("#filter_user_id") - - expect(page).to have_selector("#user_id_arg_1_val", text: 'me') - end -end \ No newline at end of file diff --git a/spec/features/grouping_spec.rb b/spec/features/grouping_spec.rb deleted file mode 100644 index daf6733d..00000000 --- a/spec/features/grouping_spec.rb +++ /dev/null @@ -1,116 +0,0 @@ -require 'spec_helper' -require_relative 'support/pages/cost_report_page' - -describe 'Cost report calculations', type: :feature, js: true do - let(:project) { FactoryBot.create :project } - let(:user) { FactoryBot.create :admin } - - let(:work_package) { FactoryBot.create :work_package, project: project } - let!(:hourly_rate1) { FactoryBot.create :default_hourly_rate, user: user, rate: 1.00, valid_from: 1.year.ago } - - let(:report_page) { ::Pages::CostReportPage.new project} - - let!(:time_entry1) { - FactoryBot.create :time_entry, - spent_on: 6.months.ago, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - before do - login_as(user) - visit cost_reports_path(project) - end - - - it 'provides grouping' do - # Then I should see "Week (Spent)" in columns - # And I should see "Work package" in rows - report_page.expect_column_element('Week (Spent)') - report_page.expect_row_element('Work package') - - # When I click on "Clear" - report_page.clear - # Then I should not see "Week (Spent)" in columns - # And I should not see "Work package" in rows - report_page.expect_column_element('Week (Spent)', present: false) - report_page.expect_row_element('Work package', present: false) - - # And I group rows by "User" - report_page.add_to_rows 'User' - # And I group rows by "Cost type" - report_page.add_to_rows 'Cost type' - - # When I click on "Clear" - report_page.clear - - # Then I should not see "Week (Spent)" in columns - # And I should not see "Work package" in rows - report_page.expect_column_element('Week (Spent)', present: false) - report_page.expect_row_element('Work package', present: false) - # And I should not see "User" in rows - # And I should not see "Cost type" in rows - report_page.expect_row_element('User', present: false) - report_page.expect_row_element('Cost type', present: false) - - # When I click on "Clear" - report_page.clear - # And I group columns by "Work package" - report_page.add_to_columns 'Work package' - - # Then I should see "Work package" in columns - report_page.expect_column_element('Work package') - # When I group rows by "Project" - report_page.add_to_columns 'Project' - # Then I should see "Project" in rows - report_page.expect_column_element('Project') - - # When I click on "Clear" - report_page.clear - # And I group columns by "Work package" - report_page.add_to_columns 'Work package' - # And I group rows by "Project" - report_page.add_to_rows 'Project' - - # Then I should see "Work package" in columns - report_page.expect_column_element('Work package') - # And I should see "Project" in rows - report_page.expect_row_element('Project') - - # When I remove "Project" from rows - report_page.remove_row_element('Project') - - # And I remove "Work package" from columns - report_page.remove_column_element('Work package') - - # Then I should not see "Work package" in columns - report_page.expect_column_element('Work package', present: false) - # And I should not see "Project" in rows - report_page.expect_row_element('Project', present: false) - - # When I click on "Clear" - report_page.clear - - # And I group columns by "Project" - report_page.add_to_columns 'Project' - # And I group columns by "Work package" - report_page.add_to_columns 'Work package' - # And I group rows by "User" - report_page.add_to_rows 'User' - # And I group rows by "Cost type" - report_page.add_to_rows 'Cost type' - - # And I send the query - report_page.apply - - # Then I should see "Project" in columns - report_page.expect_column_element('Work package') - # And I should see "Work package" in columns - report_page.expect_column_element('Project') - # And I should see "User" in rows - report_page.expect_row_element('User') - # And I should see "Cost type" in rows - report_page.expect_row_element('Cost type') - end -end \ No newline at end of file diff --git a/spec/features/me_value_spec.rb b/spec/features/me_value_spec.rb deleted file mode 100644 index dfd9a80c..00000000 --- a/spec/features/me_value_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -require 'spec_helper' - -describe 'Cost report showing my own times', type: :feature, js: true do - let(:project) { FactoryBot.create :project } - let(:user) { FactoryBot.create :admin } - let(:user2) { FactoryBot.create :admin } - - let(:work_package) { FactoryBot.create :work_package, project: project } - let!(:hourly_rate1) { FactoryBot.create :default_hourly_rate, user: user, rate: 1.00, valid_from: 1.year.ago } - - let!(:time_entry1) { - FactoryBot.create :time_entry, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - let!(:time_entry2) { - FactoryBot.create :time_entry, - user: user2, - work_package: work_package, - project: project, - hours: 15 - } - - before do - # Login as first user - login_as user - - # Create and save cost report - visit cost_reports_path(project) - - end - - shared_examples 'me filter value' do |filter_name, filter_selector| - it 'keeps the special "me" value for the current user' do - select 'me', from: filter_selector - click_on 'Save' - fill_in 'query_name', with: 'Query ME value' - check 'query_is_public' - find('#query-icon-save-button').click - - expect(page).to have_selector('.report', text: '10.00') - - report = CostQuery.last - user_filter = report.serialized[:filters].detect { |name,_| name == filter_name } - expect(user_filter[1][:values]).to eq %w(me) - - # Login as the next user - login_as user2 - - # Create and save cost report - visit cost_report_path(report.id, project_id: project.identifier) - expect(page).to have_no_selector('.report', text: '10.00') - expect(page).to have_selector('.report', text: '15.00') - - expect(find("##{filter_selector}").value).to eq 'me' - end - end - - describe 'assignee filter' do - let(:work_package) { FactoryBot.create :work_package, project: project, assigned_to: user } - let(:work_package2) { FactoryBot.create :work_package, project: project, assigned_to: user2 } - - let!(:time_entry1) { - FactoryBot.create :time_entry, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - let!(:time_entry2) { - FactoryBot.create :time_entry, - user: user2, - work_package: work_package2, - project: project, - hours: 15 - } - - - before do - # Remove default user filter, add assignee filter - find('#rm_box_user_id .filter_rem').click - select 'Assignee', from: 'add_filter_select' - end - - it_behaves_like 'me filter value', 'AssignedToId', 'assigned_to_id_arg_1_val' - end - - describe 'user filter' do - it_behaves_like 'me filter value', 'UserId', 'user_id_arg_1_val' - end -end \ No newline at end of file diff --git a/spec/features/menu_spec.rb b/spec/features/menu_spec.rb deleted file mode 100644 index 10efef6b..00000000 --- a/spec/features/menu_spec.rb +++ /dev/null @@ -1,120 +0,0 @@ -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -# -# 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 doc/COPYRIGHT.rdoc for more details. -#++ - -require 'spec_helper' - -describe 'project menu', type: :feature do - let(:current_user) { FactoryBot.create :admin } - let!(:project) { FactoryBot.create :valid_project, identifier: 'ponyo', name: 'Ponyo' } - - before do - allow(User).to receive(:current).and_return current_user - # remove filters that might be left overs from former specs - CostQuery::Cache.reset! - end - - ## - # Depending on the current page the link to the cost reports was broken. - # This seems to be due to a peculiarity of the rails routing where - # `url_for controller: :foo` would return a link relative to the controller - # handling the current request path if the controller was routed to via a - # namespaced route. - # - # Example: - # - # `url_for controller: 'cost_reports'` will yield different results ... - # - # when on `/projects/ponyo/work_packages`: `/projects/ponyo/cost_reports` (correct) - # when on `/projects/ponyo/work_packages/calendar`: `/work_packages/cost_reports?project_id=ponyo` - # - # This is only relevant for project menu entries, not global ones (`project_id` param is nil)*. - # Meaning that you have to make sure to force the absolute URL in a project menu entry - # by specificying the controller as e.g. '/cost_reports' instead of just 'cost_reports'. - # - # Refer to `engine.rb` to see where the menu entries are declared. - # - # * May apply to routes used with parameters in general. - describe '#18788 (cost reports not found (404)) regression test' do - describe 'link to project cost reports' do - shared_examples 'it leads to the project costs reports' do - before do - visit current_path - end - - it 'leads to cost reports' do - click_on 'Cost reports' - - expect(page).to have_selector('.button--dropdown-text', text: 'Ponyo') - end - end - - context "when on the project's activity page" do - let(:current_path) { '/projects/ponyo/activity' } - - it_behaves_like 'it leads to the project costs reports' - end - - context "when on the project's calendar" do - let(:current_path) { '/projects/ponyo/work_packages/calendar' } - - it_behaves_like 'it leads to the project costs reports' - end - end - - describe 'link to global cost reports' do - shared_examples 'it leads to the cost reports' do - before do - visit current_path - end - - it 'leads to cost reports' do - # doing what no human can - click on invisible items. - # This way, we avoid having to use selenium and by that increase stability. - within '#more-menu', visible: false do - click_on 'Cost reports', visible: false - end - - # to make sure we're not seeing the project cost reports: - expect(page).not_to have_text('Ponyo') - end - end - - context "when on the project's activity page" do - let(:current_path) { '/projects/ponyo/activity' } - - it_behaves_like 'it leads to the cost reports' - end - - context "when on the project's calendar" do - let(:current_path) { '/projects/ponyo/work_packages/calendar' } - - it_behaves_like 'it leads to the cost reports' - end - end - end -end diff --git a/spec/features/my_time_spec.rb b/spec/features/my_time_spec.rb deleted file mode 100644 index b61d38e7..00000000 --- a/spec/features/my_time_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'spec_helper' - -describe 'Cost report showing my own times', type: :feature, js: true do - let(:project) { FactoryBot.create :project } - let(:user) { FactoryBot.create :admin } - let(:user2) { FactoryBot.create :admin } - - let(:work_package) { FactoryBot.create :work_package, project: project } - let!(:hourly_rate1) { FactoryBot.create :default_hourly_rate, user: user, rate: 1.00, valid_from: 1.year.ago } - - let!(:time_entry1) { - FactoryBot.create :time_entry, - user: user, - work_package: work_package, - project: project, - hours: 10 - } - - before do - login_as(current_user) - visit cost_reports_path(project) - end - - - context 'as user with logged time' do - let(:current_user) { user } - it 'shows my time' do - expect(page).to have_selector('.report', text: '10.00') - end - end - - context 'as user without logged time' do - let(:current_user) { user2 } - it 'shows my time' do - expect(page).to have_no_selector('.report') - expect(page).to have_selector('.generic-table--no-results-title') - expect(page).not_to have_text '10.00' # 1 EUR x 10 - end - end -end \ No newline at end of file diff --git a/spec/features/permissions_spec.rb b/spec/features/permissions_spec.rb deleted file mode 100644 index f432921f..00000000 --- a/spec/features/permissions_spec.rb +++ /dev/null @@ -1,145 +0,0 @@ -require 'spec_helper' -require_relative 'support/pages/cost_report_page' - -describe 'Cost report calculations', type: :feature, js: true do - let(:project) { FactoryBot.create :project } - let(:admin) { FactoryBot.create :admin } - - let!(:permissions) { %i(view_cost_entries view_own_cost_entries) } - let!(:role) { FactoryBot.create :role, permissions: permissions } - let!(:user) do - FactoryBot.create :user, - member_in_project: project, - member_through_role: role - end - - let(:work_package) { FactoryBot.create :work_package, project: project } - let!(:hourly_rate_admin) { FactoryBot.create :default_hourly_rate, user: admin, rate: 1.00, valid_from: 1.year.ago } - let!(:hourly_rate_user) { FactoryBot.create :default_hourly_rate, user: user, rate: 1.00, valid_from: 1.year.ago } - - let(:report_page) { ::Pages::CostReportPage.new project } - - let!(:time_entry_user) { - FactoryBot.create :time_entry, - user: admin, - work_package: work_package, - project: project, - hours: 10 - } - let!(:time_entry_admin) { - FactoryBot.create :time_entry, - user: user, - work_package: work_package, - project: project, - hours: 5 - } - let!(:cost_type) { - type = FactoryBot.create :cost_type, name: 'Translations' - FactoryBot.create :cost_rate, cost_type: type, rate: 7.00 - type - } - let!(:cost_entry_user) { - FactoryBot.create :cost_entry, - work_package: work_package, - project: project, - units: 3.00, - cost_type: cost_type, - user: user - } - - before do - login_as current_user - visit '/cost_reports?set_filter=1' - end - - context 'as anonymous' do - let(:current_user) { User.anonymous } - it 'is redirect to login' do - expect(page).to have_content 'Login' - expect(page).to have_content 'Password' - end - end - - context 'as admin' do - let(:current_user) { admin } - - it 'shows everything' do - expect(page).to have_content '5.00 hours' - expect(page).to have_content '10.00 hours' - - report_page.switch_to_type 'Translations' - - expect(page).to have_content '3.0 plural_unit' - expect(page).to have_content '21.00 EUR' - end - end - - context 'as user with all permissions' do - let(:current_user) { user } - let!(:permissions) do - %i(view_own_hourly_rate view_hourly_rates view_cost_rates - view_own_time_entries view_own_cost_entries view_cost_entries - view_time_entries) - end - - it 'shows everything' do - expect(page).to have_content '5.00 hours' - expect(page).to have_content '10.00 hours' - report_page.switch_to_type 'Translations' - expect(page).to have_selector('td.units', text: '3.0 plural_unit', wait: 10) - end - end - - context 'as user with no permissions' do - let(:current_user) { user } - let!(:permissions) { %i() } - - it 'shows nothing' do - expect(page).to have_selector('h2', text: '403') - end - end - - context 'as user with own permissions' do - let(:current_user) { user } - let!(:permissions) do - %i(view_own_hourly_rate view_own_time_entries view_own_cost_entries) - end - - it 'shows his own costs' do - expect(page).to have_content '5.00 hours' - expect(page).not_to have_content '10.00 hours' - report_page.switch_to_type 'Translations' - expect(page).to have_selector('td.units', text: '3.0 plural_unit', wait: 10) - end - end - - context 'as user with own time permissions' do - let(:current_user) { user } - let!(:permissions) do - %i(view_own_time_entries) - end - - it 'shows his own time only' do - expect(page).to have_content '5.00 hours' - expect(page).not_to have_content '10.00 hours' - - report_page.switch_to_type 'Translations' - expect(page).to have_selector('.generic-table--no-results-title') - expect(page).to have_no_selector('td.unit', text: '3.0 plural_unit') - end - end - context 'as user with own costs permissions' do - let(:current_user) { user } - let!(:permissions) do - %i(view_own_cost_entries) - end - - it 'shows his own costs' do - expect(page).to have_selector('.generic-table--no-results-title') - expect(page).not_to have_content '5.00 hours' - expect(page).not_to have_content '10.00 hours' - report_page.switch_to_type 'Translations' - expect(page).to have_no_selector('td.unit', text: '3.0 plural_unit') - end - end -end \ No newline at end of file diff --git a/spec/features/project_context_spec.rb b/spec/features/project_context_spec.rb deleted file mode 100644 index 21d0a06a..00000000 --- a/spec/features/project_context_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'spec_helper' -require_relative 'support/pages/cost_report_page' - -describe 'Cost report project context', type: :feature, js: true do - let(:project1) { FactoryBot.create :project } - let(:project2) { FactoryBot.create :project } - let(:admin) { FactoryBot.create :admin } - - let(:report_page) { ::Pages::CostReportPage.new project } - - before do - project1 - project2 - login_as admin - end - - it "switches the project context when visiting another project's cost report" do - visit cost_reports_path(project1) - expect(page).to have_selector('#project_id_arg_1_val option', text: project1.name) - - visit cost_reports_path(project2) - expect(page).to have_selector('#project_id_arg_1_val option', text: project2.name) - end -end \ No newline at end of file diff --git a/spec/features/saving_spec.rb b/spec/features/saving_spec.rb deleted file mode 100644 index f37ec58e..00000000 --- a/spec/features/saving_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'spec_helper' -require_relative 'support/pages/cost_report_page' - -describe 'Cost report saving', type: :feature, js: true do - let(:project) { FactoryBot.create :project } - let(:user) { FactoryBot.create :admin } - - let(:report_page) { ::Pages::CostReportPage.new project } - - before do - login_as(user) - visit cost_reports_path(project) - end - - it 'can save reports privately' do - report_page.clear - - report_page.add_to_columns 'Work package' - report_page.add_to_rows 'Project' - - report_page.save as: 'Testreport' - - expect(page).to have_selector('#ur_caption', text: 'Testreport') - expect(page).to have_selector('#private_sidebar_report_list', text: 'Testreport') - - report_page.expect_column_element 'Work package' - report_page.expect_row_element 'Project' - end - - it 'can save reports publicly' do - report_page.clear - - report_page.add_to_columns 'Work package' - report_page.add_to_rows 'Project' - - report_page.save as: 'Public report', public: true - - expect(page).to have_selector('#ur_caption', text: 'Public report') - expect(page).to have_selector('#public_sidebar_report_list', text: 'Public report') - - report_page.expect_column_element 'Work package' - report_page.expect_row_element 'Project' - end - - context 'as user without permissions' do - let(:role) { FactoryBot.create :role, permissions: %i(view_time_entries) } - let!(:user) do - FactoryBot.create :user, - member_in_project: project, - member_through_role: role - end - - it 'cannot save reports' do - expect(page).to have_no_selector('.buttons', text: 'Save') - end - end -end diff --git a/spec/features/subproject_spec.rb b/spec/features/subproject_spec.rb deleted file mode 100644 index fef21134..00000000 --- a/spec/features/subproject_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe 'Cost report in subproject', type: :feature, js: true do - let!(:project) { FactoryBot.create :project } - let!(:subproject) { FactoryBot.create :project, parent: project } - - let!(:role) { FactoryBot.create :role, permissions: %i(view_cost_entries view_own_cost_entries) } - let!(:user) do - FactoryBot.create :user, - member_in_project: subproject, - member_through_role: role - end - - before do - login_as(user) - visit project_path(subproject) - end - - it 'provides filtering' do - within '#main-menu' do - click_on 'Cost reports' - end - - within '#content' do - expect(page).to have_content 'New cost report' - end - end -end \ No newline at end of file diff --git a/spec/features/support/pages/cost_report_page.rb b/spec/features/support/pages/cost_report_page.rb deleted file mode 100644 index f2d62e9e..00000000 --- a/spec/features/support/pages/cost_report_page.rb +++ /dev/null @@ -1,86 +0,0 @@ -module Pages - class CostReportPage < ::Pages::Page - attr_reader :project - - def initialize(project) - @project = project - end - - def clear - # We often clear the page as the first action of the example, - # which is why the frontend might not be fully initialized - retry_block do - scroll_to_and_click(find('#query-link-clear', text: 'Clear')) - - # Safeguard to force waiting for the form to be cleared - expect(page) - .not_to have_selector('.group-by--selected-element') - end - end - - def save(as:, public: false) - # Scroll to report bottom and click - scroll_to_and_click(find('#query-icon-save-as', text: 'Save')) - - # Ensure the form is visible - scroll_to_element find('#save_as_form') - - page.within('#save_as_form') do - fill_in 'Name', with: as - - if public - check 'Public' - end - - click_on 'Save' - end - end - - def switch_to_type(label) - choose label - apply - end - - def remove_row_element(text) - element_name = find("#group-by--rows label", text: text)[:for] - find("##{element_name}_remove").click - end - - def remove_column_element(text) - element_name = find("#group-by--columns label", text: text)[:for] - find("##{element_name}_remove").click - end - - def apply - scroll_to_and_click(find("[id='query-icon-apply-button']")) - end - - def add_to_rows(name) - select name, from: 'group-by--add-rows' - end - - def add_to_columns(name) - select name, from: 'group-by--add-columns' - end - - def expect_row_element(text, present: true) - if present - expect(page).to have_selector('#group-by--selected-rows .group-by--selected-element', text: text) - else - expect(page).to have_no_selector('#group-by--selected-rows .group-by--selected-element', text: text) - end - end - - def expect_column_element(text, present: true) - if present - expect(page).to have_selector('#group-by--selected-columns .group-by--selected-element', text: text) - else - expect(page).to have_no_selector('#group-by--selected-columns .group-by--selected-element', text: text) - end - end - - def path - cost_reports_path(project) - end - end -end diff --git a/spec/features/update_cost_report_spec.rb b/spec/features/update_cost_report_spec.rb deleted file mode 100644 index 1f256344..00000000 --- a/spec/features/update_cost_report_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -#-- copyright -# OpenProject Costs Plugin -# -# Copyright (C) 2009 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb') -require_relative 'support/pages/cost_report_page' - -describe "updating a cost report's cost type", type: :feature, js: true do - let(:project) { FactoryBot.create :project_with_types } - let(:user) do - FactoryBot.create(:admin).tap do |user| - project.add_member! user, FactoryBot.create(:role) - end - end - - let(:cost_type) do - FactoryBot.create :cost_type, name: 'Post-war', unit: 'cap', unit_plural: 'caps' - end - - let!(:cost_entry) do - FactoryBot.create :cost_entry, user: user, project: project, cost_type: cost_type - end - - let(:report_page) { ::Pages::CostReportPage.new project } - - before do - login_as(user) - end - - it 'works' do - report_page.visit! - report_page.save(as: 'My Query', public: true) - - report_page.switch_to_type cost_type.name - - click_on "Save" - - click_on "My Query" - - option = all("[name=unit]").last - - expect(option).to be_checked - expect(option.value).to eq cost_type.id.to_s - end -end diff --git a/spec/lib/open_project/configuration_spec.rb b/spec/lib/open_project/configuration_spec.rb deleted file mode 100644 index 228cc829..00000000 --- a/spec/lib/open_project/configuration_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require 'spec_helper' - -describe 'OpenProject::Configuration' do - context '.cost_reporting_cache_filter_classes' do - before do - # This prevents the values from the actual configuration file to influence - # the test outcome. - # - # TODO: I propose to port this over to the core to always prevent this for specs. - OpenProject::Configuration.load(file: 'bogus') - end - - after do - # resetting for now to avoid braking specs, who by now rely on having the file read. - OpenProject::Configuration.load - end - - it 'is a true by default via the method' do - expect(OpenProject::Configuration.cost_reporting_cache_filter_classes).to be_truthy - end - - - it 'is true by default via the hash' do - expect(OpenProject::Configuration['cost_reporting_cache_filter_classes']).to be_truthy - end - - end -end diff --git a/spec/lib/open_project/reporting/default_data_spec.rb b/spec/lib/open_project/reporting/default_data_spec.rb deleted file mode 100644 index f98b23dc..00000000 --- a/spec/lib/open_project/reporting/default_data_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -# -# 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 doc/COPYRIGHT.rdoc for more details. -#++ - -require 'spec_helper' - -describe OpenProject::Reporting::DefaultData do - let(:seeder) { BasicData::RoleSeeder.new } - let(:project_admin) { OpenProject::Reporting::DefaultData.project_admin_role } - let(:permissions) do - OpenProject::Reporting::DefaultData.restricted_project_admin_permissions - end - - before do - allow(seeder).to receive(:builtin_roles).and_return([]) - - seeder.seed! - end - - it 'removes permissions from the project admin role' do - expect(project_admin.permissions).not_to include *permissions - end - - it 'is not loaded again on existing data' do - project_admin.add_permission! *permissions - project_admin.save! - - # on existing data the permissions should not be removed - seeder.seed! - - project_admin.reload - expect(project_admin.permissions).to include *permissions - end -end diff --git a/spec/models/cost_query/cache_spec.rb b/spec/models/cost_query/cache_spec.rb deleted file mode 100644 index 5594fe11..00000000 --- a/spec/models/cost_query/cache_spec.rb +++ /dev/null @@ -1,124 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require 'spec_helper' -require File.join(File.dirname(__FILE__), '..', '..', 'support', 'configuration_helper') - -describe CostQuery::Cache do - include OpenProject::Reporting::SpecHelper::ConfigurationHelper - - def all_caches - [ CostQuery::GroupBy::CustomFieldEntries, - CostQuery::GroupBy, - CostQuery::Filter::CustomFieldEntries, - CostQuery::Filter ] - end - - def expect_reset_on_caches - all_caches.each do |klass| - expect(klass).to receive(:reset!) - end - end - - def expect_no_reset_on_caches - all_caches.each do |klass| - expect(klass).to_not receive(:reset!) - end - end - - def reset_cache_keys - # resetting internal caching keys to avoid dependencies with other specs - described_class.send(:latest_custom_field_change=, nil) - described_class.send(:custom_field_count=, 0) - end - - def custom_fields_exist - allow(WorkPackageCustomField).to receive(:maximum).and_return(Time.now) - allow(WorkPackageCustomField).to receive(:count).and_return(23) - end - - def no_custom_fields_exist - allow(WorkPackageCustomField).to receive(:maximum).and_return(nil) - allow(WorkPackageCustomField).to receive(:count).and_return(0) - end - - before do - reset_cache_keys - end - - after do - reset_cache_keys - end - - describe '.check' do - - context 'with cache_classes configuration enabled' do - before do - mock_cache_classes_setting_with(true) - end - - it 'resets the caches on filters and group by' do - custom_fields_exist - expect_reset_on_caches - - described_class.check - end - - it 'stores when the last update was made and does not reset again if nothing changed' do - custom_fields_exist - expect_reset_on_caches - - described_class.check - - expect_no_reset_on_caches - - described_class.check - end - - it 'does reset the cache if last CustomField is removed' do - custom_fields_exist - expect_reset_on_caches - - described_class.check - - no_custom_fields_exist - expect_reset_on_caches - - described_class.check - end - end - - context 'with_cache_classes configuration disabled' do - before do - mock_cache_classes_setting_with(false) - end - - it 'resets the cache again even if nothing changed' do - custom_fields_exist - expect_reset_on_caches - - described_class.check - - expect_reset_on_caches - - described_class.check - end - end - end -end diff --git a/spec/models/cost_query/chaining_spec.rb b/spec/models/cost_query/chaining_spec.rb deleted file mode 100644 index 86d555f2..00000000 --- a/spec/models/cost_query/chaining_spec.rb +++ /dev/null @@ -1,322 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') - -describe CostQuery, type: :model, reporting_query_helper: true do - let(:project) { FactoryBot.create(:project) } - - minimal_query - - describe '#chain' do - before do - #FIXME: is there a better way to load all filter and groups? - CostQuery::Filter.all && CostQuery::GroupBy.all - CostQuery.chain_initializer.clear - end - - after(:all) do - CostQuery.chain_initializer.clear - end - - it "should contain NoFilter" do - expect(@query.chain).to be_a(CostQuery::Filter::NoFilter) - end - - it "should keep NoFilter at bottom" do - @query.filter :project_id - expect(@query.chain.bottom).to be_a(CostQuery::Filter::NoFilter) - expect(@query.chain.top).not_to be_a(CostQuery::Filter::NoFilter) - end - - it "should remember it's correct parent" do - @query.group_by :project_id - @query.filter :project_id - expect(@query.chain.top.child.child.parent).to eq(@query.chain.top.child) - end - - it "should place filter after a group_by" do - @query.group_by :project_id - expect(@query.chain.bottom.parent).to be_a(CostQuery::GroupBy::ProjectId) - expect(@query.chain.top).to be_a(CostQuery::GroupBy::ProjectId) - - @query.filter :project_id - expect(@query.chain.bottom.parent).to be_a(CostQuery::Filter::ProjectId) - expect(@query.chain.top).to be_a(CostQuery::GroupBy::ProjectId) - end - - it "should place rows in front of columns when adding a column first" do - @query.column :project_id - expect(@query.chain.bottom.parent.type).to eq(:column) - expect(@query.chain.top.type).to eq(:column) - - @query.row :project_id - expect(@query.chain.bottom.parent.type).to eq(:column) - expect(@query.chain.top.type).to eq(:row) - end - - it "should place rows in front of columns when adding a row first" do - skip "This fails unreproducible on travis" if ENV['CI'] - @query.row :project_id - expect(@query.chain.bottom.parent.type).to eq(:row) - expect(@query.chain.top.type).to eq(:row) - - @query.column :project_id - expect(@query.chain.bottom.parent.type).to eq(:column) - expect(@query.chain.top.type).to eq(:row) - end - - it "should place rows in front of filters" do - @query.row :project_id - expect(@query.chain.bottom.parent.type).to eq(:row) - expect(@query.chain.top.type).to eq(:row) - - @query.filter :project_id - expect(@query.chain.bottom.parent).to be_a(CostQuery::Filter::ProjectId) - expect(@query.chain.top).to be_a(CostQuery::GroupBy::ProjectId) - expect(@query.chain.top.type).to eq(:row) - end - - it "should place columns in front of filters" do - skip "This fails unreproducible on travis" if ENV['CI'] - @query.column :project_id - expect(@query.chain.bottom.parent.type).to eq(:column) - expect(@query.chain.top.type).to eq(:column) - - @query.filter :project_id - expect(@query.chain.bottom.parent).to be_a(CostQuery::Filter::ProjectId) - expect(@query.chain.top).to be_a(CostQuery::GroupBy::Base) - expect(@query.chain.top.type).to eq(:column) - end - - it "should return all filters, including the NoFilter" do - @query.filter :project_id - @query.group_by :project_id - expect(@query.filters.size).to eq(2) - expect(@query.filters.map {|f| f.class.underscore_name}).to include "project_id" - end - - it "should return all group_bys" do - @query.filter :project_id - @query.group_by :project_id - expect(@query.group_bys.size).to eq(1) - expect(@query.group_bys.map {|g| g.class.underscore_name}).to include "project_id" - end - - it "should initialize the chain through a block" do - class TestFilter < Report::Filter::Base - def self.engine - CostQuery - end - end - TestFilter.send(:initialize_query_with) {|query| query.filter(:project_id, value: project.id)} - @query.build_new_chain - expect(@query.filters.map {|f| f.class.underscore_name}).to include "project_id" - expect(@query.filters.detect {|f| f.class.underscore_name == "project_id"}.values).to eq(Array(project.id)) - end - - context "store and load" do - before do - @query.filter :project_id, value: project.id - @query.filter :cost_type_id, value: CostQuery::Filter::CostTypeId.available_values.first - @query.filter :category_id, value: CostQuery::Filter::CategoryId.available_values.first - @query.group_by :activity_id - @query.group_by :cost_object_id - @query.group_by :cost_type_id - @new_query = CostQuery.deserialize(@query.serialize) - end - - it "should serialize the chain correctly" do - [:filters, :group_bys].each do |type| - @query.send(type).each do |chainable| - expect(@query.serialize[type].collect{|c| c[0]}).to include chainable.class.name.demodulize - end - end - end - - it "should deserialize a serialized query correctly" do - expect(@new_query.serialize).to eq(@query.serialize) - end - - it "should keep the order of group bys" do - @query.group_bys.each_with_index do |group_by, index| - # check for order - @new_query.group_bys.each_with_index do |g, ix| - if g.class.name == group_by.class.name - expect(ix).to eq(index) - end - end - end - end - - it "should keep the right filter values" do - @query.filters.each_with_index do |filter, index| - # check for presence - expect(@new_query.filters.any? do |f| - f.class.name == filter.class.name && (filter.respond_to?(:values) ? f.values == filter.values : true) - end).to be_truthy - end - end - end - end - - describe Report::Chainable do - describe '#top' do - before { @chain = Report::Chainable.new } - - it "returns for an one element long chain that chain as top" do - expect(@chain.top).to eq(@chain) - expect(@chain).to be_top - end - - it "does not keep the old top when prepending elements" do - Report::Chainable.new @chain - expect(@chain.top).not_to eq(@chain) - expect(@chain).not_to be_top - end - - it "sets new top when prepending elements" do - current = @chain - 10.times do - old, current = current, CostQuery::Chainable.new(current) - expect(old.top).to eq(current) - expect(@chain.top).to eq(current) - end - end - end - - describe '#inherited_attribute' do - before do - @a = Class.new Report::Chainable - @a.inherited_attribute :foo, default: 42 - @b = Class.new @a - @c = Class.new @a - @d = Class.new @b - end - - it 'takes default argument' do - expect(@a.foo).to eq(42) - expect(@b.foo).to eq(42) - expect(@c.foo).to eq(42) - expect(@d.foo).to eq(42) - end - - it 'inherits values' do - @a.foo 1337 - expect(@d.foo).to eq(1337) - end - - it 'does not change values of parents and akin' do - @b.foo 1337 - expect(@a.foo).not_to eq(1337) - expect(@c.foo).not_to eq(1337) - end - - it 'is able to map values' do - @a.inherited_attribute :bar, map: proc { |x| x*2 } - @a.bar 21 - expect(@a.bar).to eq(42) - end - - describe '#list' do - it "merges lists" do - @a.inherited_attribute :bar, list: true - @a.bar 1; @b.bar 2; @d.bar 3, 4 - expect(@a.bar).to eq([1]) - expect(@b.bar.sort).to eq([1, 2]) - expect(@c.bar.sort).to eq([1]) - expect(@d.bar.sort).to eq([1, 2, 3, 4]) - end - - it "is able to map lists" do - @a.inherited_attribute :bar, list: true, map: :to_s - @a.bar 1; @b.bar 1; @d.bar 1 - expect(@a.bar).to eq(%w[1]) - expect(@b.bar).to eq(%w[1 1]) - expect(@c.bar).to eq(%w[1]) - expect(@d.bar).to eq(%w[1 1 1]) - end - - it "is able to produce uniq lists" do - @a.inherited_attribute :bar, list: true, uniq: true - @a.bar 1, 1, 2 - @b.bar 2, 3 - expect(@b.bar.sort).to eq([1, 2, 3]) - end - - it "keeps old entries" do - @a.inherited_attribute :bar, list: true - @a.bar 1 - @a.bar 2 - expect(@a.bar.sort).to eq([1, 2]) - end - end - end - - describe '#display' do - it "should give display? == false when a filter says dont_display!" do - class TestFilter < Report::Filter::Base - dont_display! - end - expect(TestFilter.display?).to be false - Object.send(:remove_const, :TestFilter) - end - - it "should give display? == true when a filter doesn't specify it's visibility" do - class TestFilter < Report::Filter::Base - end - expect(TestFilter.display?).to be true - Object.send(:remove_const, :TestFilter) - end - - it "should give display? == true when a filter says display!" do - class TestFilter < Report::Filter::Base - display! - end - expect(TestFilter.display?).to be true - Object.send(:remove_const, :TestFilter) - end - end - - describe '#selectable' do - it "should give selectable? == false when a filter says not_selectable!" do - class TestFilter < Report::Filter::Base - not_selectable! - end - expect(TestFilter.selectable?).to be false - Object.send(:remove_const, :TestFilter) - end - - it "should give selectable? == true when a filter doesn't specify it's selectability" do - class TestFilter < Report::Filter::Base - end - expect(TestFilter.selectable?).to be true - Object.send(:remove_const, :TestFilter) - end - - it "should give selectable? == true when a filter says selectable!" do - class TestFilter < Report::Filter::Base - selectable! - end - expect(TestFilter.selectable?).to be true - Object.send(:remove_const, :TestFilter) - end - end - end -end diff --git a/spec/models/cost_query/cost_query_spec.rb b/spec/models/cost_query/cost_query_spec.rb deleted file mode 100644 index bdafe702..00000000 --- a/spec/models/cost_query/cost_query_spec.rb +++ /dev/null @@ -1,106 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.dirname(__FILE__) + '/../../spec_helper' - -describe User, "#destroy", type: :model do - let(:substitute_user) { DeletedUser.first } - let(:private_query) { FactoryBot.create(:private_cost_query) } - let(:public_query) { FactoryBot.create(:public_cost_query) } - let(:user) { FactoryBot.create(:user) } - let(:user2) { FactoryBot.create(:user) } - - describe "WHEN the user has saved private cost queries" do - - before do - private_query.user.destroy - end - - it { expect(CostQuery.find_by_id(private_query.id)).to eq(nil) } - end - - describe "WHEN the user has saved public cost queries" do - before do - public_query.user.destroy - end - - it { expect(CostQuery.find_by_id(public_query.id)).to eq(public_query) } - it { expect(public_query.reload.user_id).to eq(substitute_user.id) } - end - - shared_examples_for "public query" do - let(:filter_symbol) { filter.to_s.demodulize.underscore.to_sym } - - describe "WHEN the filter has the deleted user as it's value" do - before do - public_query.filter(filter_symbol, values: [user.id.to_s], operator: "=") - public_query.save! - - user.destroy - end - - it { expect(CostQuery.find_by_id(public_query.id).deserialize.filters.any?{ |f| f.is_a?(filter) }).to be_falsey } - end - - describe "WHEN the filter has another user as it's value" do - before do - public_query.filter(filter_symbol, values: [user2.id.to_s], operator: "=") - public_query.save! - - user.destroy - end - - it { expect(CostQuery.find_by_id(public_query.id).deserialize.filters.any?{ |f| f.is_a?(filter) }).to be_truthy } - it { expect(CostQuery.find_by_id(public_query.id).deserialize.filters.detect{ |f| f.is_a?(filter) }.values).to eq([user2.id.to_s]) } - end - - describe "WHEN the filter has the deleted user and another user as it's value" do - before do - public_query.filter(filter_symbol, values: [user.id.to_s, user2.id.to_s], operator: "=") - public_query.save! - - user.destroy - end - - it { expect(CostQuery.find_by_id(public_query.id).deserialize.filters.any?{ |f| f.is_a?(filter) }).to be_truthy } - it { expect(CostQuery.find_by_id(public_query.id).deserialize.filters.detect{ |f| f.is_a?(filter) }.values).to eq([user2.id.to_s]) } - end - end - - describe "WHEN someone has saved a public cost query - WHEN the query has a user_id filter" do - let(:filter) { CostQuery::Filter::UserId } - - it_should_behave_like "public query" - end - - describe "WHEN someone has saved a public cost query - WHEN the query has a author_id filter" do - let(:filter) { CostQuery::Filter::AuthorId } - - it_should_behave_like "public query" - end - - describe "WHEN someone has saved a public cost query - WHEN the query has a assigned_to_id filter" do - let(:filter) { CostQuery::Filter::AssignedToId } - - it_should_behave_like "public query" - end -end diff --git a/spec/models/cost_query/filter_spec.rb b/spec/models/cost_query/filter_spec.rb deleted file mode 100644 index 3fb2915e..00000000 --- a/spec/models/cost_query/filter_spec.rb +++ /dev/null @@ -1,447 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') -require File.join(File.dirname(__FILE__), '..', '..', 'support', 'custom_field_filter') - -describe CostQuery, type: :model, reporting_query_helper: true do - minimal_query - - let!(:project) { FactoryBot.create(:project_with_types) } - let!(:user) { FactoryBot.create(:user, member_in_project: project) } - - def create_work_package_with_entry(entry_type, work_package_params={}, entry_params = {}) - work_package_params = {project: project}.merge!(work_package_params) - work_package = FactoryBot.create(:work_package, work_package_params) - entry_params = {work_package: work_package, - project: work_package_params[:project], - user: user}.merge!(entry_params) - FactoryBot.create(entry_type, entry_params) - work_package - end - - describe CostQuery::Filter do - def create_work_package_with_time_entry(work_package_params={}, entry_params = {}) - create_work_package_with_entry(:time_entry, work_package_params, entry_params) - end - - it "shows all entries when no filter is applied" do - expect(@query.result.count).to eq(Entry.count) - end - - it "always sets cost_type" do - @query.result.each do |result| - expect(result["cost_type"]).not_to be_nil - end - end - - it "sets activity_id to -1 for cost entries" do - @query.result.each do |result| - expect(result["activity_id"].to_i).to eq(-1) if result["type"] != "TimeEntry" - end - end - - # Test Work Package attributes that are included in of the result set - - [ - [CostQuery::Filter::ProjectId, 'project', "project_id", 2], - [CostQuery::Filter::UserId, 'user', "user_id", 2], - [CostQuery::Filter::CostTypeId, 'cost_type', "cost_type_id", 1], - [CostQuery::Filter::WorkPackageId, 'work_package', "work_package_id", 2], - [CostQuery::Filter::ActivityId, 'activity', "activity_id", 1], - ].each do |filter, object_name, field, expected_count| - describe filter do - let!(:non_matching_entry) { FactoryBot.create(:cost_entry) } - let!(:object) { send(object_name) } - let!(:author) { FactoryBot.create(:user, member_in_project: project) } - let!(:work_package) { FactoryBot.create(:work_package, project: project, - author: author) } - let!(:cost_type) { FactoryBot.create(:cost_type) } - let!(:cost_entry) { FactoryBot.create(:cost_entry, work_package: work_package, - user: user, - project: project, - cost_type: cost_type) } - let!(:activity) { FactoryBot.create(:time_entry_activity) } - let!(:time_entry) { FactoryBot.create(:time_entry, work_package: work_package, - user: user, - project: project, - activity: activity) } - - it "should only return entries from the given #{filter.to_s}" do - @query.filter field, value: object.id - @query.result.each do |result| - expect(result[field].to_s).to eq(object.id.to_s) - end - end - - it "should allow chaining the same filter" do - @query.filter field, value: object.id - @query.filter field, value: object.id - @query.result.each do |result| - expect(result[field].to_s).to eq(object.id.to_s) - end - end - - it "should return no results for excluding filters" do - @query.filter field, value: object.id - @query.filter field, value: object.id + 1 - expect(@query.result.count).to eq(0) - end - - it "should compute the correct number of results" do - @query.filter field, value: object.id - expect(@query.result.count).to eq(expected_count) - end - end - end - - # Test author attribute separately as it is not included in the result set - - describe CostQuery::Filter::AuthorId do - let!(:non_matching_entry) { FactoryBot.create(:cost_entry) } - let!(:author) { FactoryBot.create(:user, member_in_project: project) } - let!(:work_package) { FactoryBot.create(:work_package, project: project, - author: author) } - let!(:cost_type) { FactoryBot.create(:cost_type) } - let!(:cost_entry) { FactoryBot.create(:cost_entry, work_package: work_package, - user: user, - project: project, - cost_type: cost_type) } - let!(:activity) { FactoryBot.create(:time_entry_activity) } - let!(:time_entry) { FactoryBot.create(:time_entry, work_package: work_package, - user: user, - project: project, - activity: activity) } - - it "should only return entries from the given CostQuery::Filter::AuthorId" do - @query.filter 'author_id', value: author.id - @query.result.each do |result| - work_package_id = result["work_package_id"] - expect(WorkPackage.find(work_package_id).author.id).to eq(author.id) - end - end - - it "should allow chaining the same filter" do - @query.filter 'author_id', value: author.id - @query.filter 'author_id', value: author.id - @query.result.each do |result| - work_package_id = result["work_package_id"] - expect(WorkPackage.find(work_package_id).author.id).to eq(author.id) - end - end - - it "should return no results for excluding filters" do - @query.filter 'author_id', value: author.id - @query.filter 'author_id', value: author.id + 1 - expect(@query.result.count).to eq(0) - end - - it "should compute the correct number of results" do - @query.filter 'author_id', value: author.id - expect(@query.result.count).to eq(2) - end - end - - it "filters spent_on" do - @query.filter :spent_on, operator: 'w' - expect(@query.result.count).to eq(Entry.all.select { |e| e.spent_on.cweek == TimeEntry.all.first.spent_on.cweek }.count) - end - - it "filters created_on" do - @query.filter :created_on, operator: 't' - # we assume that some of our fixtures set created_on to Time.now - expect(@query.result.count).to eq(Entry.all.select { |e| e.created_on.to_date == Date.today }.count) - end - - it "filters updated_on" do - @query.filter :updated_on, value: Date.today.years_ago(20), operator: '>d' - # we assume that our were updated in the last 20 years - expect(@query.result.count).to eq(Entry.all.select { |e| e.updated_on.to_date > Date.today.years_ago(20) }.count) - end - - it "filters user_id" do - old_user = User.current - # create non-matching entry - anonymous = FactoryBot.create(:anonymous) - create_work_package_with_time_entry({}, {user: anonymous}) - # create matching entry - create_work_package_with_time_entry() - @query.filter :user_id, value: user.id, operator: '=' - expect(@query.result.count).to eq(1) - end - - describe "work_package-based filters" do - def create_work_packages_and_time_entries(entry_count, work_package_params={}, entry_params={}) - entry_count.times do - create_work_package_with_entry(:cost_entry, work_package_params, entry_params) - end - end - - def create_matching_object_with_time_entries(factory, work_package_field, entry_count) - object = FactoryBot.create(factory) - create_work_packages_and_time_entries(entry_count, {work_package_field => object}) - object - end - - it "filters overridden_costs" do - @query.filter :overridden_costs, operator: 'y' - expect(@query.result.count).to eq(Entry.all.select { |e| not e.overridden_costs.nil? }.count) - end - - it "filters status" do - matching_status = FactoryBot.create(:status, is_closed: true) - create_work_packages_and_time_entries(3, status: matching_status) - @query.filter :status_id, operator: 'c' - expect(@query.result.count).to eq(3) - end - - it "filters types" do - matching_type = project.types.first - create_work_packages_and_time_entries(3, type: matching_type) - @query.filter :type_id, operator: '=', value: matching_type.id - expect(@query.result.count).to eq(3) - end - - it "filters work_package authors" do - matching_author = create_matching_object_with_time_entries(:user, :author, 3) - @query.filter :author_id, operator: '=', value: matching_author.id - expect(@query.result.count).to eq(3) - end - - it "filters priority" do - matching_priority = create_matching_object_with_time_entries(:priority, :priority, 3) - @query.filter :priority_id, operator: '=', value: matching_priority.id - expect(@query.result.count).to eq(3) - end - - it "filters assigned to" do - matching_user = create_matching_object_with_time_entries(:user, :assigned_to, 3) - @query.filter :assigned_to_id, operator: '=', value: matching_user.id - expect(@query.result.count).to eq(3) - end - - it "filters category" do - category = FactoryBot.create(:category, project: project) - create_work_packages_and_time_entries(3, category: category) - @query.filter :category_id, operator: '=', value: category.id - expect(@query.result.count).to eq(3) - end - - it "filters target version" do - matching_version = FactoryBot.create(:version, project: project) - create_work_packages_and_time_entries(3, fixed_version: matching_version) - - @query.filter :fixed_version_id, operator: '=', value: matching_version.id - expect(@query.result.count).to eq(3) - end - - it "filters subject" do - matching_work_package = create_work_package_with_time_entry(subject: 'matching subject') - @query.filter :subject, operator: '=', value: 'matching subject' - expect(@query.result.count).to eq(1) - end - - it "filters start" do - start_date = Date.new(2013, 1, 1) - matching_work_package = create_work_package_with_time_entry(start_date: start_date) - @query.filter :start_date, operator: '=d', value: start_date - expect(@query.result.count).to eq(1) - #Entry.all.select { |e| e.work_package.start_date == WorkPackage.all(:order => "id ASC").first.start_date }.count - end - - it "filters due date" do - due_date = Date.new(2013, 1, 1) - matching_work_package = create_work_package_with_time_entry(due_date: due_date) - @query.filter :due_date, operator: '=d', value: due_date - expect(@query.result.count).to eq(1) - #Entry.all.select { |e| e.work_package.due_date == WorkPackage.all(:order => "id ASC").first.due_date }.count - end - - it "raises an error if operator is not supported" do - expect { @query.filter :spent_on, operator: 'c' }.to raise_error(ArgumentError) - end - end - - #filter for specific objects, which can't be null - [ - CostQuery::Filter::UserId, - CostQuery::Filter::CostTypeId, - CostQuery::Filter::AuthorId, - CostQuery::Filter::ActivityId, - CostQuery::Filter::PriorityId, - CostQuery::Filter::TypeId - ].each do |filter| - it "should only allow default operators for #{filter}" do - expect(filter.new.available_operators.uniq.sort).to eq(CostQuery::Operator.default_operators.uniq.sort) - end - end - - #filter for specific objects, which might be null - [ - CostQuery::Filter::AssignedToId, - CostQuery::Filter::CategoryId, - CostQuery::Filter::FixedVersionId - ].each do |filter| - it "should only allow default+null operators for #{filter}" do - expect(filter.new.available_operators.uniq.sort).to eq((CostQuery::Operator.default_operators + CostQuery::Operator.null_operators).sort) - end - end - - #filter for specific objects, which can only have the default operator - [ - CostQuery::Filter::WorkPackageId, - ].each do |filter| - it "should only allow default operators for #{filter}" do - expect(filter.new.available_operators.uniq).to match_array([CostQuery::Operator.default_operator]) - end - end - - #filter for time/date - [ - CostQuery::Filter::CreatedOn, - CostQuery::Filter::UpdatedOn, - CostQuery::Filter::SpentOn, - CostQuery::Filter::StartDate, - CostQuery::Filter::DueDate - ].each do |filter| - it "should only allow time operators for #{filter}" do - expect(filter.new.available_operators.uniq.sort).to eq(CostQuery::Operator.time_operators.sort) - end - end - - describe CostQuery::Filter::CustomFieldEntries do - let!(:custom_field) do - cf = FactoryBot.create(:work_package_custom_field, - name: 'My custom field') - clear_cache - cf - end - - let(:custom_field2) do - FactoryBot.build(:work_package_custom_field, name: 'Database', - field_format: "list", - possible_values: ['value']) - end - - after(:all) do - clear_cache - end - - def clear_cache - CostQuery::Cache.reset! - CostQuery::Filter::CustomFieldEntries.all - end - - def delete_work_package_custom_field(cf) - cf.destroy - clear_cache - end - - def update_work_package_custom_field(name, options) - fld = WorkPackageCustomField.find_by(name: name) - options.each_pair {|k, v| fld.send(:"#{k}=", v) } - fld.save! - clear_cache - end - - include OpenProject::Reporting::SpecHelper::CustomFieldFilterHelper - - it "should create classes for custom fields that get added after starting the server" do - custom_field - expect { filter_class_name_string(custom_field).constantize }.not_to raise_error - end - - it "should remove the custom field classes after it is deleted" do - custom_field - class_name = filter_class_name_string(custom_field) - delete_work_package_custom_field(custom_field) - expect { filter_class_name_string(custom_field).constantize }.to raise_error NameError - end - - it "should provide the correct available values" do - custom_field2.save - - clear_cache - ao = filter_class_name_string(custom_field2).constantize.available_operators.map(&:name) - CostQuery::Operator.null_operators.each do |o| - expect(ao).to include o.name - end - end - - it "should update the available values on change" do - custom_field2.save - - update_work_package_custom_field("Database", field_format: "string") - ao = filter_class_name_string(custom_field2).constantize.available_operators.map(&:name) - CostQuery::Operator.string_operators.each do |o| - expect(ao).to include o.name - end - update_work_package_custom_field("Database", field_format: "int") - ao = filter_class_name_string(custom_field2).constantize.available_operators.map(&:name) - CostQuery::Operator.integer_operators.each do |o| - expect(ao).to include o.name - end - end - - it "includes custom fields classes in CustomFieldEntries.all" do - custom_field - expect(CostQuery::Filter::CustomFieldEntries.all). - to include(filter_class_name_string(custom_field).constantize) - end - - it "includes custom fields classes in Filter.all" do - custom_field - expect(CostQuery::Filter.all). - to include(filter_class_name_string(custom_field).constantize) - end - - def create_searchable_fields_and_values - searchable_field = FactoryBot.create(:work_package_custom_field, - field_format: "text", - name: "Searchable Field") - 2.times do - work_package = create_work_package_with_entry(:cost_entry) - FactoryBot.create(:work_package_custom_value, - custom_field: searchable_field, - customized: work_package, - value: "125") - end - work_package = create_work_package_with_entry(:cost_entry) - FactoryBot.create(:custom_value, - custom_field: searchable_field, - value: "non-matching value") - clear_cache - end - - it "is usable as filter" do - create_searchable_fields_and_values - id = WorkPackageCustomField.find_by(name: "Searchable Field").id - @query.filter "custom_field_#{id}".to_sym, operator: '=', value: "125" - expect(@query.result.count).to eq(2) - end - - it "is usable as filter #2" do - create_searchable_fields_and_values - id = WorkPackageCustomField.find_by(name: "Searchable Field").id - @query.filter "custom_field_#{id}".to_sym, operator: '=', value: "finnlabs" - expect(@query.result.count).to eq(0) - end - end - end -end diff --git a/spec/models/cost_query/group_by_spec.rb b/spec/models/cost_query/group_by_spec.rb deleted file mode 100644 index 70d82dd2..00000000 --- a/spec/models/cost_query/group_by_spec.rb +++ /dev/null @@ -1,294 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') -require File.join(File.dirname(__FILE__), '..', '..', 'support', 'custom_field_filter') - -describe CostQuery, type: :model, reporting_query_helper: true do - let!(:type) { FactoryBot.create(:type) } - let!(:project1){ FactoryBot.create(:project_with_types, types: [type]) } - let!(:work_package1) { FactoryBot.create(:work_package, project: project1, type: type)} - let!(:time_entry1) { FactoryBot.create(:time_entry, work_package: work_package1, project: project1, spent_on: Date.new(2012, 1, 1)) } - let!(:time_entry2) do - time_entry2 = time_entry1.dup - time_entry2.save! - time_entry2 - end - let!(:cost_object1) { FactoryBot.create(:cost_object, project: project1) } - let!(:cost_entry1) { FactoryBot.create(:cost_entry, work_package: work_package1, project: project1, spent_on: Date.new(2013, 2, 3)) } - let!(:cost_entry2) do - cost_entry2 = cost_entry1.dup - cost_entry2.save! - cost_entry2 - end - - let!(:project2) { FactoryBot.create(:project_with_types, types: [type]) } - let!(:work_package2) { FactoryBot.create(:work_package, project: project2, type: type) } - let!(:time_entry3) { FactoryBot.create(:time_entry, work_package: work_package2, project: project2, spent_on: Date.new(2013, 2, 3)) } - let!(:time_entry4) do - time_entry4 = time_entry3.dup - time_entry4.save! - time_entry4 - end - let!(:cost_object2) { FactoryBot.create(:cost_object, project: project2) } - let!(:cost_entry3) { FactoryBot.create(:cost_entry, work_package: work_package2, project: project2, spent_on: Date.new(2012, 1, 1)) } - let!(:cost_entry4) do - cost_entry4 = cost_entry3.dup - cost_entry4.save! - cost_entry4 - end - - minimal_query - - describe CostQuery::GroupBy do - it "should compute group_by on projects" do - @query.group_by :project_id - expect(@query.result.size).to eq(2) - end - - it "should keep own and all parents' group fields in all_group_fields" do - @query.group_by :project_id - @query.group_by :work_package_id - @query.group_by :cost_type_id - expect(@query.all_group_fields).to eq(%w[entries.cost_type_id]) - expect(@query.child.all_group_fields).to eq(%w[entries.cost_type_id entries.work_package_id]) - expect(@query.child.child.all_group_fields).to eq(%w[entries.cost_type_id entries.work_package_id entries.project_id]) - end - - it "should compute group_by WorkPackage" do - @query.group_by :work_package_id - expect(@query.result.size).to eq(2) - end - - it "should compute group_by CostType" do - @query.group_by :cost_type_id - # type 'Labor' for time entries, 2 different cost types - expect(@query.result.size).to eq(3) - end - - it "should compute group_by Activity" do - @query.group_by :activity_id - # "-1" for time entries, 2 different cost activities - expect(@query.result.size).to eq(3) - end - - it "should compute group_by Date (day)" do - @query.group_by :spent_on - expect(@query.result.size).to eq(2) - end - - it "should compute group_by Date (week)" do - @query.group_by :tweek - expect(@query.result.size).to eq(2) - end - - it "should compute group_by Date (month)" do - @query.group_by :tmonth - expect(@query.result.size).to eq(2) - end - - it "should compute group_by Date (year)" do - @query.group_by :tyear - expect(@query.result.size).to eq(2) - end - - it "should compute group_by User" do - @query.group_by :user_id - expect(@query.result.size).to eq(4) - end - - it "should compute group_by Type" do - @query.group_by :type_id - expect(@query.result.size).to eq(1) - end - - it "should compute group_by CostObject" do - @query.group_by :cost_object_id - expect(@query.result.size).to eq(1) - end - - it "should compute multiple group_by" do - @query.group_by :project_id - @query.group_by :user_id - sql_result = @query.result - - expect(sql_result.size).to eq(4) - # for each user the number of projects should be correct - sql_sizes = [] - sql_result.each do |sub_result| - # user should be the outmost group_by - expect(sub_result.fields).to include(:user_id) - sql_sizes.push sub_result.size - sub_result.each { |sub_sub_result| expect(sub_sub_result.fields).to include(:project_id) } - end - expect(sql_sizes.sort).to eq([1, 1, 1, 1]) - end - - # TODO: ? - it "should compute multiple group_by with joins" do - @query.group_by :project_id - @query.group_by :type_id - sql_result = @query.result - expect(sql_result.size).to eq(1) - # for each type the number of projects should be correct - sql_sizes = [] - sql_result.each do |sub_result| - # type should be the outmost group_by - expect(sub_result.fields).to include(:type_id) - sql_sizes.push sub_result.size - sub_result.each { |sub_sub_result| expect(sub_sub_result.fields).to include(:project_id) } - end - expect(sql_sizes.sort).to eq([2]) - end - - it "compute count correct with lots of group_by" do - @query.group_by :project_id - @query.group_by :work_package_id - @query.group_by :cost_type_id - @query.group_by :activity_id - @query.group_by :spent_on - @query.group_by :tweek - @query.group_by :type_id - @query.group_by :tmonth - @query.group_by :tyear - - expect(@query.result.count).to eq(8) - end - - it "should accept row as a specialised group_by" do - @query.row :project_id - expect(@query.chain.type).to eq(:row) - end - - it "should accept column as a specialised group_by" do - @query.column :project_id - expect(@query.chain.type).to eq(:column) - end - - it "should have type :column as a default" do - @query.group_by :project_id - expect(@query.chain.type).to eq(:column) - end - - it "should aggregate a third group_by which owns at least 2 sub results" do - - @query.group_by :tweek - @query.group_by :project_id - @query.group_by :user_id - sql_result = @query.result - - expect(sql_result.size).to eq(4) - # for each user the number of projects should be correct - sql_sizes = [] - sub_sql_sizes = [] - sql_result.each do |sub_result| - # user should be the outmost group_by - expect(sub_result.fields).to include(:user_id) - sql_sizes.push sub_result.size - - sub_result.each do |sub_sub_result| - expect(sub_sub_result.fields).to include(:project_id) - sub_sql_sizes.push sub_sub_result.size - - sub_sub_result.each do |sub_sub_sub_result| - expect(sub_sub_sub_result.fields).to include(:tweek) - end - end - end - expect(sql_sizes.sort).to eq([1, 1, 1, 1]) - expect(sub_sql_sizes.sort).to eq([1, 1, 1, 1]) - end - - describe CostQuery::GroupBy::CustomFieldEntries do - let!(:project){ FactoryBot.create(:project_with_types) } - let!(:custom_field) do - FactoryBot.create(:work_package_custom_field) - end - - let(:custom_field2) do - FactoryBot.build(:work_package_custom_field) - end - - before do - check_cache - CostQuery::GroupBy.all.merge CostQuery::GroupBy::CustomFieldEntries.all - end - - def check_cache - CostQuery::Cache.reset! - CostQuery::GroupBy::CustomFieldEntries.all - end - - def delete_work_package_custom_field(custom_field) - custom_field.destroy - check_cache - end - - include OpenProject::Reporting::SpecHelper::CustomFieldFilterHelper - - it "should create classes for custom fields" do - # Would raise a name error - expect { group_by_class_name_string(custom_field).constantize }.to_not raise_error - end - - it "should create new classes for custom fields that get added after starting the server" do - custom_field2.save! - - check_cache - - # Would raise a name error - expect { group_by_class_name_string(custom_field2).constantize }.to_not raise_error - - custom_field2.destroy - end - - it "should remove the custom field classes after it is deleted" do - custom_field2.save! - - check_cache - - custom_field2.destroy - - check_cache - - expect { group_by_class_name_string(custom_field2).constantize }.to raise_error NameError - end - - it "includes custom fields classes in CustomFieldEntries.all" do - expect(CostQuery::GroupBy::CustomFieldEntries.all). - to include(group_by_class_name_string(custom_field).constantize) - end - - it "includes custom fields classes in GroupBy.all" do - expect(CostQuery::GroupBy.all). - to include(group_by_class_name_string(custom_field).constantize) - end - - it "is usable as filter" do - custom_field2.save! - - check_cache - - @query.group_by "custom_field_#{custom_field2.id}".to_sym - footprint = @query.result.each_direct_result.map { |c| [c.count, c.units.to_i] }.sort - expect(footprint).to eq([[8, 8]]) - end - end - end -end diff --git a/spec/models/cost_query/integration_spec.rb b/spec/models/cost_query/integration_spec.rb deleted file mode 100644 index 5aec3aa6..00000000 --- a/spec/models/cost_query/integration_spec.rb +++ /dev/null @@ -1,105 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') - -describe CostQuery, type: :model, reporting_query_helper: true do - minimal_query - - let!(:project1){ FactoryBot.create(:project_with_types) } - let!(:work_package1) { FactoryBot.create(:work_package, project: project1) } - let!(:time_entry1) { FactoryBot.create(:time_entry, work_package: work_package1, project: project1) } - let!(:time_entry2) { FactoryBot.create(:time_entry, work_package: work_package1, project: project1) } - - let!(:project2) { FactoryBot.create(:project_with_types) } - let!(:work_package2) { FactoryBot.create(:work_package, project: project2) } - let!(:time_entry3) { FactoryBot.create(:time_entry, work_package: work_package2, project: project2) } - let!(:time_entry4) { FactoryBot.create(:time_entry, work_package: work_package2, project: project2) } - - before do - FactoryBot.create(:admin) - end - - describe "the reporting system" do - it "should compute group_by and a filter" do - @query.group_by :project_id - @query.filter :status_id, operator: 'o' - sql_result = @query.result - - expect(sql_result.size).to eq(2) - #for each project the number of entries should be correct - sql_count = [] - sql_result.each do |sub_result| - #project should be the outmost group_by - expect(sub_result.fields).to include(:project_id) - sql_count.push sub_result.count - end - expect(sql_count.sort).to eq([2, 2]) - end - - it "should apply two filter and a group_by correctly" do - @query.filter :project_id, operator: '=', value: [project1.id] - @query.group_by :user_id - @query.filter :overridden_costs, operator: 'n' - - sql_result = @query.result - expect(sql_result.size).to eq(2) - #for each user the number of entries should be correct - sql_count = [] - sql_result.each do |sub_result| - #project should be the outmost group_by - expect(sub_result.fields).to include(:user_id) - sql_count.push sub_result.count - end - expect(sql_count.sort).to eq([1, 1]) - end - - it "should apply two different filters on the same field" do - @query.filter :project_id, operator: '=', value: [project1.id, project2.id] - @query.filter :project_id, operator: '!', value: [project2.id] - - sql_result = @query.result - expect(sql_result.count).to eq(2) - end - - it 'should process only _one_ SQL query for any operations on a valid CostQuery' do - number_of_sql_queries = 0 - expect_any_instance_of(CostQuery::SqlStatement).to receive(:to_s) do |*_| - number_of_sql_queries += 1 unless caller.third.include? 'sql_statement.rb' - - # Apparently, we have to return a valid SQL query - - 'SELECT 1=1' - end - - # create a random query - @query.group_by :work_package_id - @query.column :tweek - @query.row :project_id - @query.row :user_id - # count how often a sql query was created - number_of_sql_queries = 0 - # do some random things on it - walker = @query.transformer - walker.row_first - walker.column_first - # TODO - to do something - end - end -end diff --git a/spec/models/cost_query/operator_spec.rb b/spec/models/cost_query/operator_spec.rb deleted file mode 100644 index 67ed3bd4..00000000 --- a/spec/models/cost_query/operator_spec.rb +++ /dev/null @@ -1,270 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') - -describe CostQuery, type: :model, reporting_query_helper: true do - minimal_query - - let!(:project1) { FactoryBot.create(:project, name: "project1", created_on: 5.minutes.ago) } - let!(:project2) { FactoryBot.create(:project, name: "project2", created_on: 6.minutes.ago) } - - describe CostQuery::Operator do - def query(table, field, operator, *values) - sql = CostQuery::SqlStatement.new table - yield sql if block_given? - operator.to_operator.modify sql, field, *values - ActiveRecord::Base.connection.select_all(sql.to_s).to_a - end - - def query_on_entries(field, operator, *values) - sql = CostQuery::SqlStatement.for_entries - operator.to_operator.modify sql, field, *values - ActiveRecord::Base.connection.select_all(sql.to_s).to_a - end - - def create_project(options = {}) - parent = options.delete :parent - p = FactoryBot.create(:project, options) - p.set_parent! parent if parent - p - end - - it "does =" do - expect(query('projects', 'id', '=', project1.id).size).to eq(1) - end - - it "does = for multiple values" do - expect(query('projects', 'id', '=', project1.id, project2.id).size).to eq(2) - end - - it "does = for no values" do - sql = CostQuery::SqlStatement.new 'projects' - "=".to_operator.modify sql, 'id' - result = (ActiveRecord::Base.connection.select_all sql.to_s) - expect(result).to be_empty - end - - it "does = for nil" do - expect(query('projects', 'id', '=', nil).size).to eq(0) - end - - it "does <=" do - expect(query('projects', 'id', '<=', project2.id - 1).size).to eq(1) - end - - it "does >=" do - expect(query('projects', 'id', '>=', project1.id + 1).size).to eq(1) - end - - it "does !" do - expect(query('projects', 'id', '!', project1.id).size).to eq(1) - end - - it "does ! for multiple values" do - expect(query('projects', 'id', '!', project1.id, project2.id).size).to eq(0) - end - - it "does !*" do - expect(query('cost_entries', 'project_id', '!*', []).size).to eq(0) - end - - it "does ~ (contains)" do - expect(query('projects', 'name', '~', 'o').size).to eq(Project.all.select { |p| p.name =~ /o/ }.count) - expect(query('projects', 'name', '~', 'test').size).to eq(Project.all.select { |p| p.name =~ /test/ }.count) - expect(query('projects', 'name', '~', 'child').size).to eq(Project.all.select { |p| p.name =~ /child/ }.count) - end - - it "does !~ (not contains)" do - expect(query('projects', 'name', '!~', 'o').size).to eq(Project.all.select { |p| p.name !~ /o/ }.count) - expect(query('projects', 'name', '!~', 'test').size).to eq(Project.all.select { |p| p.name !~ /test/ }.count) - expect(query('projects', 'name', '!~', 'child').size).to eq(Project.all.select { |p| p.name !~ /child/ }.count) - end - - it "does c (closed work_package)" do - expect(query('work_packages', 'status_id', 'c') { |s| s.join Status => [WorkPackage, :status] }.size).to be >= 0 - end - - it "does o (open work_package)" do - expect(query('work_packages', 'status_id', 'o') { |s| s.join Status => [WorkPackage, :status] }.size).to be >= 0 - end - - it "does give the correct number of results when counting closed and open work_packages" do - a = query('work_packages', 'status_id', 'o') { |s| s.join Status => [WorkPackage, :status] }.size - b = query('work_packages', 'status_id', 'c') { |s| s.join Status => [WorkPackage, :status] }.size - expect(WorkPackage.count).to eq(a + b) - end - - it "does w (this week)" do - #somehow this test doesn't work on sundays - n = query('projects', 'created_on', 'w').size - day_in_this_week = Time.now.at_beginning_of_week + 1.day - FactoryBot.create(:project, created_on: day_in_this_week) - expect(query('projects', 'created_on', 'w').size).to eq(n + 1) - FactoryBot.create(:project, created_on: day_in_this_week + 7.days) - FactoryBot.create(:project, created_on: day_in_this_week - 7.days) - expect(query('projects', 'created_on', 'w').size).to eq(n + 1) - end - - it "does t (today)" do - s = query('projects', 'created_on', 't').size - FactoryBot.create(:project, created_on: Date.yesterday) - expect(query('projects', 'created_on', 't').size).to eq(s) - FactoryBot.create(:project, created_on: Time.now) - expect(query('projects', 'created_on', 't').size).to eq(s + 1) - end - - it "does t+ (after the day which is n days in the furure)" do - n = query('projects', 'created_on', '>t+', 1).size - FactoryBot.create(:project, created_on: Time.now) - expect(query('projects', 'created_on', '>t+', 1).size).to eq(n) - FactoryBot.create(:project, created_on: Date.tomorrow + 1) - expect(query('projects', 'created_on', '>t+', 1).size).to eq(n + 1) - end - - it "does >t- (after the day which is n days ago)" do - n = query('projects', 'created_on', '>t-', 1).size - FactoryBot.create(:project, created_on: Date.today) - expect(query('projects', 'created_on', '>t-', 1).size).to eq(n + 1) - FactoryBot.create(:project, created_on: Date.yesterday - 1) - expect(query('projects', 'created_on', '>t-', 1).size).to eq(n + 1) - end - - it "does t- (n days ago)" do - n = query('projects', 'created_on', 't-', 1).size - FactoryBot.create(:project, created_on: Date.yesterday) - expect(query('projects', 'created_on', 't-', 1).size).to eq(n + 1) - FactoryBot.create(:project, created_on: Date.yesterday - 2) - expect(query('projects', 'created_on', 't-', 1).size).to eq(n + 1) - end - - it "does d" do - expect(query('projects', 'created_on', '<>d', Time.now, 5.minutes.from_now).size).to eq(0) - end - - it "does >d" do - #assuming that all projects were created in the past - expect(query('projects', 'created_on', '>d', Time.now).size).to eq(0) - end - - describe 'arity' do - arities = {'t' => 0, 'w' => 0, '<>d' => 2, '>d' => 1} - arities.each do |o,a| - it("#{o} should take #{a} values") { expect(o.to_operator.arity).to eq(a) } - end - end - - end -end diff --git a/spec/models/cost_query/result_spec.rb b/spec/models/cost_query/result_spec.rb deleted file mode 100644 index bcc9fc82..00000000 --- a/spec/models/cost_query/result_spec.rb +++ /dev/null @@ -1,147 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') - -describe CostQuery, type: :model, reporting_query_helper: true do - before do - FactoryBot.create(:admin) - project = FactoryBot.create(:project_with_types) - work_package = FactoryBot.create(:work_package, project: project) - FactoryBot.create(:time_entry, work_package: work_package, project: project) - FactoryBot.create(:cost_entry, work_package: work_package, project: project) - end - - minimal_query - - describe CostQuery::Result do - def direct_results(quantity = 0) - (1..quantity).map {|i| CostQuery::Result.new real_costs:i.to_f, count:1 ,units:i.to_f} - end - - def wrapped_result(source, quantity=1) - CostQuery::Result.new((1..quantity).map { |i| source}) - end - - it "should travel recursively depth-first" do - #build a tree of wrapped and direct results - w1 = wrapped_result((direct_results 5), 3) - w2 = wrapped_result wrapped_result((direct_results 3), 2) - w = wrapped_result [w1, w2] - previous_depth = -1 - w.recursive_each_with_level do |level, result| - #depth first, so we should get deeper into the hole, until we find a direct_result - expect(previous_depth).to eq(level - 1) - previous_depth=level - break if result.is_a? CostQuery::Result::DirectResult - end - end - - it "should travel recursively width-first" do - #build a tree of wrapped and direct results - w1 = wrapped_result((direct_results 5), 3) - w2 = wrapped_result wrapped_result((direct_results 3), 2) - w = wrapped_result [w1, w2] - - previous_depth = -1 - w.recursive_each_with_level 0, false do |level, result| - #width first, so we should get only deeper into the hole without ever coming up again - expect(previous_depth).to be <= level - previous_depth=level - end - end - - it "should travel to all results width-first" do - #build a tree of wrapped and direct results - w1 = wrapped_result((direct_results 5), 3) - w2 = wrapped_result wrapped_result((direct_results 3), 2) - w = wrapped_result [w1, w2] - - count = 0 - w.recursive_each_with_level 0, false do |level, result| - #width first - count = count + 1 if result.is_a? CostQuery::Result::DirectResult - end - expect(w.count).to eq(count) - end - - it "should travel to all results width-first" do - #build a tree of wrapped and direct results - w1 = wrapped_result((direct_results 5), 3) - w2 = wrapped_result wrapped_result((direct_results 3), 2) - w = wrapped_result [w1, w2] - - count = 0 - w.recursive_each_with_level do |level, result| - #depth first - count = count + 1 if result.is_a? CostQuery::Result::DirectResult - end - expect(w.count).to eq(count) - end - - it "should compute count correctly" do - expect(@query.result.count).to eq(Entry.count) - end - - it "should compute units correctly" do - expect(@query.result.units).to eq(Entry.all.map { |e| e.units}.sum) - end - - it "should compute real_costs correctly" do - expect(@query.result.real_costs).to eq(Entry.all.map { |e| e.overridden_costs || e.costs}.sum) - end - - it "should compute count for DirectResults" do - expect(@query.result.values[0].count).to eq(1) - end - - it "should compute units for DirectResults" do - id_sorted = @query.result.values.sort_by { |r| r[:id] } - te_result = id_sorted.select { |r| r[:type]==TimeEntry.to_s }.first - ce_result = id_sorted.select { |r| r[:type]==CostEntry.to_s }.first - expect(te_result.units.to_s).to eq("1.0") - expect(ce_result.units.to_s).to eq("1.0") - end - - it "should compute real_costs for DirectResults" do - id_sorted = @query.result.values.sort_by { |r| r[:id] } - [CostEntry].each do |type| - result = id_sorted.select { |r| r[:type]==type.to_s }.first - first = type.all.first - expect(result.real_costs).to eq(first.overridden_costs || first.costs) - end - end - - it "should be a column if created with CostQuery.column" do - @query.column :project_id - expect(@query.result.type).to eq(:column) - end - - it "should be a row if created with CostQuery.row" do - @query.row :project_id - expect(@query.result.type).to eq(:row) - end - - it "should show the type :direct for its direct results" do - @query.column :project_id - expect(@query.result.first.first.type).to eq(:direct) - end - - end -end diff --git a/spec/models/cost_query/validation_spec.rb b/spec/models/cost_query/validation_spec.rb deleted file mode 100644 index a481f357..00000000 --- a/spec/models/cost_query/validation_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') - -describe "CostQuery::Validation", type: :model do - class CostQuery::SomeBase - include CostQuery::Validation - end - - it "should be valid with no validations whatsoever" do - obj = CostQuery::SomeBase.new - expect(obj.validate("foo")).to be_truthy - expect(obj.validations.size).to eq(0) - end - - it "should allow for multiple validations" do - obj = CostQuery::SomeBase.new - obj.register_validations([:integers, :dates]) - expect(obj.validations.size).to eq(2) - end - - it "should have errors set when we try to validate something invalid" do - obj = CostQuery::SomeBase.new - obj.register_validation(:integers) - expect(obj.validate("this ain't a number, right?")).to be_falsey - expect(obj.errors[:int].size).to eq(1) - end - - it "should have no errors set when we try to validate something valid" do - obj = CostQuery::SomeBase.new - obj.register_validation(:integers) - expect(obj.validate(1,2,3,4)).to be_truthy - expect(obj.errors[:int].size).to eq(0) - end - - it "should validate integers correctly" do - obj = CostQuery::SomeBase.new - obj.register_validation(:integers) - expect(obj.validate(1,2,3,4)).to be_truthy - expect(obj.errors[:int].size).to eq(0) - expect(obj.validate("I ain't gonna work on Maggies Farm no more")).to be_falsey - expect(obj.errors[:int].size).to eq(1) - expect(obj.validate("You've got the touch!", "You've got the power!")).to be_falsey - expect(obj.errors[:int].size).to eq(2) - expect(obj.validate(1, "This is a good burger")).to be_falsey - expect(obj.errors[:int].size).to eq(1) - end - - it "should validate dates correctly" do - obj = CostQuery::SomeBase.new - obj.register_validation(:dates) - expect(obj.validate("2010-04-15")).to be_truthy - expect(obj.errors[:date].size).to eq(0) - expect(obj.validate("2010-15-15")).to be_falsey - expect(obj.errors[:date].size).to eq(1) - expect(obj.validate("2010-04-31")).to be_falsey - expect(obj.errors[:date].size).to eq(1) - end - -end diff --git a/spec/models/cost_query/walker_spec.rb b/spec/models/cost_query/walker_spec.rb deleted file mode 100644 index 79d71f0f..00000000 --- a/spec/models/cost_query/walker_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') - -describe CostQuery, type: :model, reporting_query_helper: true do - minimal_query - - before do - FactoryBot.create(:admin) - project = FactoryBot.create(:project_with_types) - work_package = FactoryBot.create(:work_package, project: project) - FactoryBot.create(:time_entry, work_package: work_package, project: project) - end - - describe CostQuery::Transformer do - it "should walk down row_first" do - @query.group_by :work_package_id - @query.column :tweek - @query.row :project_id - @query.row :user_id - - result = @query.transformer.row_first.values.first - [:user_id, :project_id, :tweek].each do |field| - expect(result.fields).to include(field) - result = result.values.first - end - end - - it "should walk down column_first" do - @query.group_by :work_package_id - @query.column :tweek - @query.row :project_id - @query.row :user_id - - result = @query.transformer.column_first.values.first - [:tweek, :work_package_id].each do |field| - expect(result.fields).to include(field) - result = result.values.first - end - end - end -end diff --git a/spec/requests/custom_field_cache_spec.rb b/spec/requests/custom_field_cache_spec.rb deleted file mode 100644 index 798045c3..00000000 --- a/spec/requests/custom_field_cache_spec.rb +++ /dev/null @@ -1,124 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -require 'spec_helper' -require File.join(File.dirname(__FILE__), '..', 'support', 'custom_field_filter') -require File.join(File.dirname(__FILE__), '..', 'support', 'configuration_helper') - -describe 'Custom field filter and group by caching', type: :request do - include OpenProject::Reporting::SpecHelper::CustomFieldFilterHelper - include OpenProject::Reporting::SpecHelper::ConfigurationHelper - - let(:project) { FactoryBot.create(:valid_project) } - let(:user) { FactoryBot.create(:admin) } - let(:custom_field) { FactoryBot.build(:work_package_custom_field) } - let(:custom_field2) { FactoryBot.build(:work_package_custom_field) } - - before do - allow(User).to receive(:current).and_return(user) - - custom_field.save! - end - - after do - CostQuery::Cache.reset! - end - - def expect_group_by_all_to_include(custom_field) - expect(CostQuery::GroupBy.all).to include(group_by_class_name_string(custom_field).constantize) - end - - def expect_filter_all_to_include(custom_field) - expect(CostQuery::Filter.all).to include(filter_class_name_string(custom_field).constantize) - end - - def expect_group_by_all_to_not_exist(custom_field) - # can not check for whether the element is included in CostQuery::GroupBy.all if it does not exist - expect { group_by_class_name_string(custom_field).constantize }.to raise_error NameError - end - - def expect_filter_all_to_not_exist(custom_field) - # can not check for whether the element is included in CostQuery::Filter.all if it does not exist - expect { filter_class_name_string(custom_field).constantize }.to raise_error NameError - end - - def visit_cost_reports_index - header "Content-Type", "text/html" - header 'X-Requested-With', 'XMLHttpRequest' - get "/projects/#{project.id}/cost_reports" - end - - it 'removes the filter/group_by if the custom field is removed' do - custom_field2.save! - - visit_cost_reports_index - - expect_group_by_all_to_include(custom_field) - expect_group_by_all_to_include(custom_field2) - - expect_filter_all_to_include(custom_field) - expect_filter_all_to_include(custom_field2) - - custom_field2.destroy - - visit_cost_reports_index - - expect_group_by_all_to_include(custom_field) - expect_group_by_all_to_not_exist(custom_field2) - - expect_filter_all_to_include(custom_field) - expect_filter_all_to_not_exist(custom_field2) - end - - it 'removes the filter/group_by if the last custom field is removed' do - visit_cost_reports_index - - expect_group_by_all_to_include(custom_field) - expect_filter_all_to_include(custom_field) - - custom_field.destroy - - visit_cost_reports_index - - expect_group_by_all_to_not_exist(custom_field) - expect_filter_all_to_not_exist(custom_field) - end - - it 'allows for changing the db entries directly via SQL between requests \ - if no caching is done (this could also mean switching dbs)' do - new_label = "our new label" - mock_cache_classes_setting_with(false) - - visit_cost_reports_index - - expect_group_by_all_to_include(custom_field) - expect_filter_all_to_include(custom_field) - - CustomField.where(id: custom_field.id) - .update_all(name: new_label) - - visit_cost_reports_index - - expect_group_by_all_to_include(custom_field) - expect_filter_all_to_include(custom_field) - - expect(group_by_class_name_string(custom_field).constantize.label).to eql(new_label) - expect(filter_class_name_string(custom_field).constantize.label).to eql(new_label) - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index 97edcd43..00000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,23 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -RAILS_ENV = "test" unless defined? RAILS_ENV - -require "spec_helper" -Dir[File.dirname(__FILE__) + '/support/*.rb'].each { |file| require file } diff --git a/spec/support/configuration_helper.rb b/spec/support/configuration_helper.rb deleted file mode 100644 index 0714ebbe..00000000 --- a/spec/support/configuration_helper.rb +++ /dev/null @@ -1,31 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting::SpecHelper - module ConfigurationHelper - def mock_cache_classes_setting_with(value) - allow(OpenProject::Configuration).to receive(:[]).and_call_original - allow(OpenProject::Configuration).to receive(:[]) - .with('cost_reporting_cache_filter_classes') - .and_return(value) - allow(OpenProject::Configuration).to receive(:cost_reporting_cache_filter_classes) - .and_return(value) - end - end -end diff --git a/spec/support/custom_field_filter.rb b/spec/support/custom_field_filter.rb deleted file mode 100644 index ce7aabb3..00000000 --- a/spec/support/custom_field_filter.rb +++ /dev/null @@ -1,34 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting::SpecHelper - module CustomFieldFilterHelper - def group_by_class_name_string(custom_field) - id = custom_field.is_a?(ActiveRecord::Base) ? custom_field.id : custom_field - - "CostQuery::GroupBy::CustomField#{id}" - end - - def filter_class_name_string(custom_field) - id = custom_field.is_a?(ActiveRecord::Base) ? custom_field.id : custom_field - - "CostQuery::Filter::CustomField#{id}" - end - end -end diff --git a/spec/support/plugin_spec_helper.rb b/spec/support/plugin_spec_helper.rb deleted file mode 100644 index d97a6888..00000000 --- a/spec/support/plugin_spec_helper.rb +++ /dev/null @@ -1,30 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject::Reporting - module PluginSpecHelper - def is_member(project, user, permissions = []) - role = FactoryBot.create(:role, permissions: permissions) - - FactoryBot.create(:member, project: project, - principal: user, - roles: [role]) - end - end -end diff --git a/spec/support/query_helper.rb b/spec/support/query_helper.rb deleted file mode 100644 index bb1bef76..00000000 --- a/spec/support/query_helper.rb +++ /dev/null @@ -1,36 +0,0 @@ -#-- copyright -# OpenProject Reporting Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -# need to define all the operators -require 'cost_query/operator' - -module OpenProject::Reporting - module QueryHelper - def minimal_query - before do - @query = CostQuery.new - @query.send(:minimal_chain!) - end - end - end -end - -RSpec.configure do |c| - c.extend OpenProject::Reporting::QueryHelper, reporting_query_helper: true -end