Files
openfoodnetwork/lib/reporting/report_renderer.rb
2022-05-12 16:54:14 +02:00

96 lines
2.3 KiB
Ruby

# frozen_string_literal: true
require 'spreadsheet_architect'
module Reporting
class ReportRenderer
REPORT_FORMATS = [:csv, :json, :xlsx, :pdf].freeze
def initialize(report)
@report = report
end
def raw_render?
@report.params[:report_format].in?(['json', 'csv'])
end
def html_render?
@report.params[:report_format].in?(['', 'pdf'])
end
def display_header_row?
@report.params[:display_header_row].present? && !raw_render?
end
def display_summary_row?
@report.params[:display_summary_row].present? && !raw_render?
end
def table_headers
@report.table_headers || []
end
def table_rows
@report.table_rows || []
end
def as_json(_context_controller = nil)
@report.rows.map(&:to_h).as_json
end
def render_as(target_format, controller: nil)
unless target_format.to_sym.in?(REPORT_FORMATS)
raise ActionController::BadRequest, "report_format should be in #{REPORT_FORMATS}"
end
public_send("to_#{target_format}", controller)
end
def to_csv(_context_controller = nil)
SpreadsheetArchitect.to_csv(headers: table_headers, data: table_rows)
end
def to_xlsx(_context_controller = nil)
SpreadsheetArchitect.to_xlsx(spreadsheets_options)
end
def to_pdf(context_controller)
WickedPdf.new.pdf_from_string(
context_controller.render_to_string(
template: 'admin/reports/_table',
layout: 'pdf',
locals: { report: @report }
)
)
end
private
def spreadsheets_options
{
headers: table_headers,
data: table_rows,
freeze_headers: true,
row_style: spreadsheets_style,
header_style: spreadsheets_style.merge({ bg_color: "f7f6f6", bold: true }),
conditional_row_styles: [
{
# Detect header_row: the row is nil except for first cell
if: proc { |row_data, _row_index|
row_data.compact.count == 1 && row_data[0].present?
},
styles: { font_size: 12, bold: true }
},
],
}
end
def spreadsheets_style
{
font_name: 'system-ui',
alignment: { horizontal: :left, vertical: :bottom }
}
end
end
end