app/classes/tables/summary_table_data.rb
module Tables
class SummaryTableData
def initialize(template_data)
@template_data = template_data
end
def by_fuel_type_table
fuel_type_table = {}
fuel_types.map do |fuel_type|
fuel_type_table[fuel_type] = OpenStruct.new(
week: summary_data_for(fuel_type, :workweek),
year: summary_data_for(fuel_type, :year)
)
end
OpenStruct.new(fuel_type_table)
end
def by_fuel_type
fuel_types.map do |fuel_type|
[summary_data_for(fuel_type, :workweek), summary_data_for(fuel_type, :year)]
end.flatten
end
def date_ranges
fuel_types.map do |fuel_type|
"#{I18n.t("common.#{fuel_type}", default: fuel_type.to_s.humanize)} #{I18n.t('common.data')}: #{start_date(fuel_type)} - #{end_date(fuel_type)}."
end.join(' ')
end
def table_date_ranges
table_date_ranges = {}
fuel_types.each do |fuel_type|
table_date_ranges[fuel_type] = { start_date: start_date(fuel_type), end_date: end_date(fuel_type) }
end
table_date_ranges
end
def start_date(fuel_type)
format_date(fetch(fuel_type, :start_date))
end
def end_date(fuel_type)
format_date(fetch(fuel_type, :end_date))
end
def work_week(fuel_type)
summary_data_for(fuel_type, :workweek)
end
def year(fuel_type)
summary_data_for(fuel_type, :year)
end
private
def fuel_types
@template_data.blank? ? [] : @template_data.keys
end
def summary_data_for(fuel_type, period)
OpenStruct.new(
period_key: period,
fuel_type: fuel_type,
period: format_period(period),
usage: format_number(fetch(fuel_type, period, :kwh), :kwh),
usage_text: format_number(fetch(fuel_type, period, :kwh), Float, :text),
co2: format_number(fetch(fuel_type, period, :co2), :kg),
co2_text: format_number(fetch(fuel_type, period, :co2), Float, :text),
cost: format_number(fetch(fuel_type, period, :£), :£),
cost_text: format_number(fetch(fuel_type, period, :£), Float, :text),
savings: format_number(fetch(fuel_type, period, :savings_£), :£),
savings_text: format_number(fetch(fuel_type, period, :savings_£), Float, :text),
change: format_number(fetch(fuel_type, period, :percent_change), :comparison_percent, :text),
change_text: format_number(fetch(fuel_type, period, :percent_change), :comparison_percent, :text),
message: data_validity_message(fuel_type, period),
message_class: data_validity_class(fuel_type, period),
has_data: has_data?(fuel_type, period)
)
end
def has_data?(fuel_type, period)
!no_recent_data?(fuel_type, period) && [:kwh, :co2, :£].any? { |item| fetch(fuel_type, period, item).present? }
end
def no_recent_data?(fuel_type, period)
# Originally analytics was providing a string "no recent data" for :recent, but only if it wasn't recent
# now it is a recent true/false flag.
# so: check for boolean, nil
value = fetch(fuel_type, period, :recent)
return !value if value.in? [true, false]
# otherwise its old structure
value.present? && value == I18n.t('classes.tables.summary_table_data.no_recent_data')
end
def data_validity_message(fuel_type, period)
message = fetch(fuel_type, period, :available_from)
return format_availability_message(message) if message.present?
value = fetch(fuel_type, period, :recent)
return I18n.t('classes.tables.summary_table_data.no_recent_data') if value == false
# otherwise its old structure
return value if value.present?
end
def data_validity_class(fuel_type, period)
value = fetch(fuel_type, period, :recent)
return '' if value == true
return 'old-data' if value == false
# otherwise its old structure
return 'old-data' if value.present?
end
def format_availability_message(message)
# old style
return message if message.start_with?('Data available')
# now a date
return I18n.t('classes.tables.summary_table_data.data_available_from', date: format_future_date(Date.parse(message)))
end
def format_future_date(date)
date < 30.days.from_now ? I18n.l(date, format: '%a %d %b %Y') : I18n.l(date, format: '%b %Y')
end
def format_period(period)
period == :workweek ? I18n.t('classes.tables.summary_table_data.last_week') : I18n.t('classes.tables.summary_table_data.last_year')
end
def format_date(value)
if (date = Date.parse(value))
I18n.l(date, format: '%-d %b %Y')
end
rescue
value
end
def format_number(value, units, medium = :html)
return '' if value.nil?
if Float(value)
FormatEnergyUnit.format(units, value.to_f, medium, false, true, :target).html_safe
end
rescue
I18n.t("classes.tables.summary_table_data.#{value}", default: value)
end
def fetch(fuel_type, period, item = nil)
if item && @template_data[fuel_type] && @template_data[fuel_type][period]
@template_data[fuel_type][period][item]
elsif @template_data[fuel_type]
@template_data[fuel_type][period]
end
end
end
end