limit to single xls export format

pull/7991/head
ulferts 5 years ago
parent 16bfb8465c
commit 9c42477d5a
No known key found for this signature in database
GPG Key ID: A205708DE1284017
  1. 14
      modules/xls_export/lib/open_project/xls_export/patches/cost_reports_controller_patch.rb
  2. 2
      modules/xls_export/lib/open_project/xls_export/xls_views.rb
  3. 60
      modules/xls_export/lib/open_project/xls_export/xls_views/cost_entry_table.xls.rb
  4. 157
      modules/xls_export/lib/open_project/xls_export/xls_views/cost_report_table.xls.rb
  5. 63
      modules/xls_export/lib/open_project/xls_export/xls_views/one_dimensional_table.xls.rb
  6. 63
      modules/xls_export/lib/open_project/xls_export/xls_views/simple_cost_report_table.xls.rb

@ -30,17 +30,13 @@ module OpenProject::XlsExport::Patches
end
# Build an xls file from a cost report.
# We only support extracting a simple xls table, so grouping is ignored.
def report_to_xls
options = { query: @query, project: @project, cost_types: @cost_types }
export_query = build_query(filter_params)
sb = if @query.group_bys.empty?
::OpenProject::XlsExport::XlsViews::CostEntryTable.generate(options)
elsif @query.depth_of(:column) + @query.depth_of(:row) == 1
::OpenProject::XlsExport::XlsViews::SimpleCostReportTable.generate(options)
else
::OpenProject::XlsExport::XlsViews::CostReportTable.generate(options)
end
sb.xls
options = { query: export_query, project: @project, cost_types: @cost_types }
::OpenProject::XlsExport::XlsViews::CostEntryTable.generate(options).xls
end
end
end

@ -73,5 +73,3 @@ end
# Load subclasses
require_relative './xls_views/cost_entry_table.xls'
require_relative './xls_views/simple_cost_report_table.xls'
require_relative './xls_views/cost_report_table.xls'

@ -1,6 +1,50 @@
require_relative './one_dimensional_table.xls'
class OpenProject::XlsExport::XlsViews::CostEntryTable < OpenProject::XlsExport::XlsViews
def generate
@spreadsheet = OpenProject::XlsExport::SpreadsheetBuilder.new(I18n.t(:label_money))
default_query = serialize_query_without_hidden(@query)
available_cost_type_tabs(options[:cost_types]).each_with_index do |(unit_id, name), idx|
setup_query_for_tab(default_query, unit_id)
spreadsheet.worksheet(idx, name)
build_spreadsheet
end
spreadsheet
end
def setup_query_for_tab(query, unit_id)
@query = CostQuery.deserialize(query)
@cost_type = nil
@unit_id = unit_id
if @unit_id != 0
@query.filter :cost_type_id, operator: '=', value: @unit_id.to_s
@cost_type = CostType.find(unit_id) if unit_id.positive?
end
end
def build_spreadsheet
set_title
build_header
format_columns
build_cost_rows
build_footer
spreadsheet
end
def build_header
spreadsheet.add_headers(headers)
end
def build_cost_rows
query.each_direct_result do |result|
spreadsheet.add_row(cost_row(result))
end
end
class OpenProject::XlsExport::XlsViews::CostEntryTable < OpenProject::XlsExport::XlsViews::OneDimensionalTable
def format_columns
spreadsheet.add_format_option_to_column(headers.length - 3,
number_format: number_format)
@ -25,13 +69,21 @@ class OpenProject::XlsExport::XlsViews::CostEntryTable < OpenProject::XlsExport:
def build_footer
footer = [''] * cost_entry_attributes.size
footer += if show_result(query, 0) != show_result(query)
[show_result(query), '', show_result(query, 0)]
one_unit_type_footer
else
['', '', show_result(query)]
multiple_unit_types_footer
end
spreadsheet.add_sums(footer) # footer
end
def one_unit_type_footer
[show_result(query), '', show_result(query, 0)]
end
def multiple_unit_types_footer
['', '', show_result(query)]
end
def headers
cost_entry_attributes
.map { |field| label_for(field) }

@ -1,157 +0,0 @@
class OpenProject::XlsExport::XlsViews::CostReportTable < OpenProject::XlsExport::XlsViews
def final_row(final_row, cells)
row = [show_row(final_row)]
row += cells
row << show_result(final_row)
end
def row(row, subrows)
unless row.fields.empty?
# Here we get the border setting, vertically. The rowspan #{subrows.size} need be
# converted to a proper Excel bordering
subrows = subrows.inject([]) do |array, subrow|
if subrow.flatten == subrow
array << subrow
else
array += subrow.collect(&:flatten)
end
end
subrows.each_with_index do |subrow, idx|
if idx.to_i.zero?
subrow.insert(0, show_row(row))
subrow << show_result(row)
else
subrow.unshift("")
subrow << ""
end
end
end
subrows
end
def cell(result)
show_result result
end
def headers(list, first, first_in_col, last_in_col)
if first_in_col # Open a new header row
@header = [""] * query.depth_of(:row) # TODO: needs borders: rowspan=query.depth_of(:column)
end
list.each do |column|
@header << show_row(column)
@header += [""] * (column.final_number(:column) - 1).abs
end
if last_in_col # Finish this header row
@header += [""] * query.depth_of(:row) # TODO: needs borders: rowspan=query.depth_of(:column)
@headers << @header
end
end
def footers(list, first, first_in_col, last_in_col)
if first_in_col # Open a new footer row
@footer = [""] * query.depth_of(:row) # TODO: needs borders: rowspan=query.depth_of(:column)
end
list.each do |column|
@footer << show_result(column)
@footer += [""] * (column.final_number(:column) - 1).abs
end
if last_in_col # Finish this footer row
if first
@footer << show_result(query)
@footer += [""] * (query.depth_of(:row) - 1).abs # TODO: add rowspan=query.depth_of(:column)
else
@footer += [""] * query.depth_of(:row) # TODO: add rowspan=query.depth_of(:column)
end
@footers << @footer
end
end
def body(*line)
@rows += line.flatten
end
def generate
@spreadsheet ||= OpenProject::XlsExport::SpreadsheetBuilder.new(I18n.t(:label_money))
default_query = serialize_query_without_hidden(@query)
available_cost_type_tabs(options[:cost_types]).each_with_index do |ary, idx|
@query = CostQuery.deserialize(default_query)
@unit_id = ary.first
name = ary.last
if @unit_id != 0
@query.filter :cost_type_id, operator: '=', value: @unit_id.to_s
@cost_type = CostType.find(unit_id) if unit_id.positive?
end
spreadsheet.worksheet(idx, name)
run_walker
build_spreadsheet unless (@headers + @footers).empty?
end
spreadsheet
end
def run_walker
walker = query.walker
walker.for_final_row &method(:final_row)
walker.for_row &method(:row)
walker.for_empty_cell { "" }
walker.for_cell &method(:cell)
@headers = []
@header = []
walker.headers &method(:headers)
@footers = []
@footer = []
walker.reverse_headers &method(:footers)
@rows = []
walker.body &method(:body)
end
def build_spreadsheet
set_title
spreadsheet.add_headers [label]
row_length = @headers.first.length
format_columns
@headers.each { |head| spreadsheet.add_headers(head, spreadsheet.current_row) }
@rows.in_groups_of(row_length).each { |body| spreadsheet.add_row(body) }
@footers.each { |foot| spreadsheet.add_sums(foot, spreadsheet.current_row) }
spreadsheet
end
def format_columns
return unless value_format
(query.depth_of(:row)..@headers.flatten.length).each do |index|
spreadsheet.add_format_option_to_column(index, number_format: value_format)
end
end
def value_format
if unit_id.zero?
currency_format
elsif unit_id == -1
number_format
end
end
def label
unit = case unit_id
when -1 then CostEntry.human_attribute_name(:hours)
when 0 then Setting.plugin_openproject_costs['costs_currency']
else cost_type.unit_plural
end
"#{CostType.model_name.human}: #{unit}"
end
end

@ -1,63 +0,0 @@
class OpenProject::XlsExport::XlsViews::OneDimensionalTable < OpenProject::XlsExport::XlsViews
def generate
@spreadsheet = OpenProject::XlsExport::SpreadsheetBuilder.new(I18n.t(:label_money))
default_query = serialize_query_without_hidden(@query)
available_cost_type_tabs(options[:cost_types]).each_with_index do |(unit_id, name), idx|
setup_query_for_tab(default_query, unit_id)
spreadsheet.worksheet(idx, name)
build_spreadsheet
end
spreadsheet
end
def setup_query_for_tab(query, unit_id)
@query = CostQuery.deserialize(query)
@cost_type = nil
@unit_id = unit_id
if @unit_id != 0
@query.filter :cost_type_id, operator: '=', value: @unit_id.to_s
@cost_type = CostType.find(unit_id) if unit_id.positive?
end
end
def build_spreadsheet
set_title
build_header
format_columns
build_cost_rows
build_footer
spreadsheet
end
def build_header
spreadsheet.add_headers(headers)
end
def format_columns
raise NotImplementedError
end
def build_cost_rows
query.each_direct_result do |result|
spreadsheet.add_row(cost_row(result))
end
end
def cost_row(result)
raise NotImplementedError
end
def build_footer
raise NotImplementedError
end
def headers
raise NotImplementedError
end
end

@ -1,63 +0,0 @@
require_relative './one_dimensional_table.xls'
class OpenProject::XlsExport::XlsViews::SimpleCostReportTable < OpenProject::XlsExport::XlsViews::OneDimensionalTable
def format_columns
column_count = headers.size
if column_count - exported_fields.size == 1
spreadsheet.add_format_option_to_column(column_count - 1, number_format: currency_format)
elsif column_count - exported_fields.size == 2
spreadsheet.add_format_option_to_column(column_count - 2, number_format: number_format)
else
spreadsheet.add_format_option_to_column(column_count - 2, number_format: number_format)
spreadsheet.add_format_option_to_column(column_count - 4, number_format: currency_format)
end
end
def build_cost_rows
query.each do |result|
spreadsheet.add_row(cost_row(result))
end
end
def cost_row(result)
current_cost_type_id = result.fields[:cost_type_id].to_i
row = [show_row(result)]
row << show_result(result, current_cost_type_id) if show_units?
row << cost_type_unit_label(current_cost_type_id, cost_type) if show_units?
row << show_result(result)
row << cost_type_unit_label(unit_id, cost_type) if show_unit_label?
row
end
def build_footer
footer = [''] * exported_fields.size
footer += ['', ''] if show_units?
footer << show_result(query)
footer << cost_type_unit_label(unit_id, cost_type) if show_unit_label?
spreadsheet.add_sums(footer)
end
def headers
headers = exported_fields.collect { |field| label_for(field) }
headers << CostEntry.human_attribute_name(:costs) << "" if show_units?
headers << label_for(:label_sum)
headers << "" if show_unit_label?
headers
end
def exported_fields
@query.collect(&:important_fields).flatten.uniq
end
def show_units?
cost_type.present?
end
def show_unit_label?
unit_id != 0
end
end
Loading…
Cancel
Save