Merge remote-tracking branch 'origin/release/7.2' into dev

pull/6827/head
Oliver Günther 7 years ago
commit 258cbd80a3
No known key found for this signature in database
GPG Key ID: 88872239EB414F99
  1. 4
      Gemfile.plugins
  2. 41
      app/models/cost_query/custom_field_mixin.rb
  3. 135
      spec/features/custom_fields_spec.rb

@ -1,7 +1,7 @@
# Dependencies (need to be called before the actual gem) # Dependencies (need to be called before the actual gem)
group :opf_plugins do group :opf_plugins do
gem "openproject-costs", :git => "https://github.com/finnlabs/openproject-costs.git", :branch => "dev" 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 => "dev" 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. # Used by travis to bundle this plugin with the OpenProject core.
# The tested plugin will be moved to the path `./plugins/this` # The tested plugin will be moved to the path `./plugins/this`

@ -87,7 +87,44 @@ module CostQuery::CustomFieldMixin
@class_name = class_name @class_name = class_name
dont_inherit :group_fields dont_inherit :group_fields
db_field table_name db_field table_name
join_table (<<-SQL % [CustomValue.table_name, table_name, field.id, field.name, SQL_TYPES[field.field_format]]).gsub(/^ /, '') if field.list?
join_table list_join_table(field)
else
join_table default_join_table(field)
end
instance_eval(&on_prepare)
self
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" -- BEGIN Custom Field Join: "%4$s"
LEFT OUTER JOIN ( LEFT OUTER JOIN (
\tSELECT \tSELECT
@ -103,8 +140,6 @@ module CostQuery::CustomFieldMixin
AND %2$s.customized_id = entries.work_package_id AND %2$s.customized_id = entries.work_package_id
-- END Custom Field Join: "%4$s" -- END Custom Field Join: "%4$s"
SQL SQL
instance_eval(&on_prepare)
self
end end
def new(*) def new(*)

@ -0,0 +1,135 @@
#-- 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) { FactoryGirl.create :type }
let(:project) { FactoryGirl.create :project, types: [type] }
let(:user) { FactoryGirl.create :admin }
let(:work_package) {
FactoryGirl.create :work_package,
project: project,
custom_values: initial_custom_values
}
let!(:time_entry1) {
FactoryGirl.create :time_entry,
user: user,
work_package: work_package,
project: project,
hours: 10
}
let!(:time_entry2) {
FactoryGirl.create :time_entry,
user: user,
work_package: work_package,
project: project,
hours: 2.50
}
before do
login_as(user)
visit '/cost_reports'
end
context 'with multi value cf' do
let!(:custom_field) do
FactoryGirl.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 => 1 } }
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
end
context 'with text CF' do
let(:custom_field) do
FactoryGirl.create(
:text_wp_custom_field,
name: 'Text CF',
types: [type],
projects: [project]
)
end
let(:initial_custom_values) { { custom_field.id => 'foo' } }
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
Loading…
Cancel
Save