diff --git a/lib/open_project/xls_export/formatters.rb b/lib/open_project/xls_export/formatters.rb new file mode 100644 index 0000000000..b678ad953b --- /dev/null +++ b/lib/open_project/xls_export/formatters.rb @@ -0,0 +1,78 @@ +module OpenProject::XlsExport + module Formatters + def self.all + self.constants.map do |const| + Kernel.const_get("OpenProject::XlsExport::Formatters::#{const}") + end.select do |const| + const.is_a?(Class) && const != DefaultFormatter + end + [DefaultFormatter] + end + + ## + # Returns a Hash mapping columns to formatters to be used. + def self.for_columns(columns) + formatters = self.all + entries = columns.map do |column| + [column, formatters.find { |formatter| formatter.apply? column }.new] + end + Hash[entries] + end + + class DefaultFormatter + ## + # Takes a QueryColumn and returns true if this formatter should be used to handle it. + def self.apply?(column) + true + end + + ## + # Takes a WorkPackage and a QueryColumn and returns the value to be exported. + def format(work_package, column) + column.value work_package + end + + ## + # Takes a QueryColumn and returns format options for it. + def format_options(column) + {} + end + end + + class TimeFormatter < DefaultFormatter + def self.apply?(column) + h = column.caption + h =~ /.*hours.*/ || h == "spent_time" + end + + def format_options(column) + {:number_format => "0.0 h"} + end + end + + class CostFormatter + include Redmine::I18n + include ActionView::Helpers::NumberHelper + + def self.apply?(column) + column.name.to_s =~ /.*cost.*/ + end + + def format(work_package, column) + column.real_value work_package + end + + def format_options(column) + {:number_format => excel_format_string} + end + + def excel_format_string + # [$CUR] makes sure we have an actually working currency format with arbitrary currencies + curr = "[$CUR]".gsub "CUR", ERB::Util.h(Setting.plugin_openproject_costs['costs_currency']) + format = ERB::Util.h Setting.plugin_openproject_costs['costs_currency_format'] + number = '#,##0.00' + + format.gsub("%n", number).gsub("%u", curr) + end + end + end +end diff --git a/lib/open_project/xls_export/patches/work_packages_controller_patch.rb b/lib/open_project/xls_export/patches/work_packages_controller_patch.rb index 4d48006d89..1fcbcc4c66 100644 --- a/lib/open_project/xls_export/patches/work_packages_controller_patch.rb +++ b/lib/open_project/xls_export/patches/work_packages_controller_patch.rb @@ -37,27 +37,24 @@ module OpenProject::XlsExport columns = query.columns sb = SpreadsheetBuilder.new("#{I18n.t(:label_work_package_plural)}") + formatters = OpenProject::XlsExport::Formatters.for_columns(columns) headers = columns.collect(&:caption).unshift("#") headers << WorkPackage.human_attribute_name(:description) if options[:show_descriptions] sb.add_headers headers, 0 - issues.each do |issue| + issues.each do |work_package| row = (columns.collect do |column| - cv = column.value(issue) + cv = formatters[column].format work_package, column (cv.respond_to? :name) ? cv.name : cv - end).unshift(issue.id) - row << issue.description if options[:show_descriptions] + end).unshift(work_package.id) + row << work_package.description if options[:show_descriptions] sb.add_row(row) end - headers.each_with_index do |h,idx| - h = h.to_s.downcase - if (h =~ /.*hours.*/ or h == "spent_time") - sb.add_format_option_to_column idx, :number_format => "0.0 h" - elsif (h =~ /.*cost.*/) - sb.add_format_option_to_column idx, :number_format => number_to_currency(0.00) - end + columns.each_with_index do |column, i| + options = formatters[column].format_options column + sb.add_format_option_to_column i + 1, options end sb