mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
You wouldn't want it by default, but it can be enabled with a parameter like display_summary_row=true
105 lines
2.4 KiB
Ruby
105 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spreadsheet_architect'
|
|
|
|
module Reporting
|
|
class ReportRenderer
|
|
REPORT_FORMATS = [:csv, :json, :html, :xlsx, :pdf].freeze
|
|
|
|
def initialize(report)
|
|
@report = report
|
|
end
|
|
|
|
# Strip header and summary rows for these formats
|
|
def raw_render?
|
|
@report.params[:report_format].in?(['csv'])
|
|
end
|
|
|
|
# Do not format values for these output formats
|
|
def unformatted_render?
|
|
@report.params[:report_format].in?(['json', 'csv'])
|
|
end
|
|
|
|
def html_render?
|
|
@report.params[:report_format].in?([nil, '', '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)
|
|
unless target_format.to_sym.in?(REPORT_FORMATS)
|
|
raise ActionController::BadRequest, "report_format should be in #{REPORT_FORMATS}"
|
|
end
|
|
|
|
public_send("to_#{target_format}")
|
|
end
|
|
|
|
def to_html(layout: nil)
|
|
ApplicationController.render(
|
|
template: "admin/reports/_table",
|
|
layout: layout,
|
|
locals: { report: @report }
|
|
)
|
|
end
|
|
|
|
def to_csv
|
|
SpreadsheetArchitect.to_csv(headers: table_headers, data: table_rows)
|
|
end
|
|
|
|
def to_xlsx
|
|
SpreadsheetArchitect.to_xlsx(spreadsheets_options)
|
|
end
|
|
|
|
def to_pdf
|
|
html = to_html(layout: "pdf")
|
|
WickedPdf.new.pdf_from_string(html)
|
|
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
|