Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ASCOR export #445

Merged
merged 5 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion app/controllers/tpi/ascor_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ def show
end

def user_download
render json: {}
render zip: {
'ASCOR_countries.xlsx' => Api::CSVToExcel.new(CSVExport::ASCOR::Countries.new.call).call,
'ASCOR_indicators.xlsx' => Api::CSVToExcel.new(CSVExport::ASCOR::AssessmentIndicators.new.call).call,
'ASCOR_assessments_results.xlsx' => Api::CSVToExcel.new(CSVExport::ASCOR::Assessments.new.call).call,
'ASCOR_benchmarks.xlsx' => Api::CSVToExcel.new(CSVExport::ASCOR::Benchmarks.new.call).call,
'ASCOR_assessments_results_trends_pathways.xlsx' => Api::CSVToExcel.new(CSVExport::ASCOR::Pathways.new.call).call
}, filename: "TPI ASCOR data - #{Time.now.strftime('%d%m%Y')}"
end

private
Expand Down
12 changes: 12 additions & 0 deletions app/models/ascor/assessment.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# == Schema Information
#
# Table name: ascor_assessments
#
# id :bigint not null, primary key
# country_id :bigint not null
# assessment_date :date
# publication_date :date
# created_at :datetime not null
# updated_at :datetime not null
# notes :text
#
class ASCOR::Assessment < ApplicationRecord
belongs_to :country, class_name: 'ASCOR::Country', foreign_key: :country_id

Expand Down
12 changes: 12 additions & 0 deletions app/models/ascor/assessment_indicator.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# == Schema Information
#
# Table name: ascor_assessment_indicators
#
# id :bigint not null, primary key
# indicator_type :string
# code :string
# text :text
# created_at :datetime not null
# updated_at :datetime not null
# units_or_response_type :string
#
class ASCOR::AssessmentIndicator < ApplicationRecord
INDICATOR_TYPES = %w[pillar area indicator metric].freeze
enum indicator_type: array_to_enum_hash(INDICATOR_TYPES)
Expand Down
13 changes: 13 additions & 0 deletions app/models/ascor/assessment_result.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# == Schema Information
#
# Table name: ascor_assessment_results
#
# id :bigint not null, primary key
# assessment_id :bigint not null
# indicator_id :bigint not null
# answer :string
# created_at :datetime not null
# updated_at :datetime not null
# source :string
# year :integer
#
class ASCOR::AssessmentResult < ApplicationRecord
belongs_to :assessment, class_name: 'ASCOR::Assessment', foreign_key: :assessment_id
belongs_to :indicator, class_name: 'ASCOR::AssessmentIndicator', foreign_key: :indicator_id
Expand Down
15 changes: 15 additions & 0 deletions app/models/ascor/benchmark.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# == Schema Information
#
# Table name: ascor_benchmarks
#
# id :bigint not null, primary key
# country_id :bigint not null
# publication_date :date
# emissions_metric :string
# emissions_boundary :string
# units :string
# benchmark_type :string
# emissions :jsonb
# created_at :datetime not null
# updated_at :datetime not null
#
class ASCOR::Benchmark < ApplicationRecord
include HasEmissions

Expand Down
15 changes: 15 additions & 0 deletions app/models/ascor/country.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# == Schema Information
#
# Table name: ascor_countries
#
# id :bigint not null, primary key
# name :string
# slug :string
# iso :string
# region :string
# wb_lending_group :string
# fiscal_monitor_category :string
# created_at :datetime not null
# updated_at :datetime not null
# type_of_party :string
#
class ASCOR::Country < ApplicationRecord
extend FriendlyId

Expand Down
24 changes: 24 additions & 0 deletions app/models/ascor/pathway.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# == Schema Information
#
# Table name: ascor_pathways
#
# id :bigint not null, primary key
# country_id :bigint not null
# emissions_metric :string
# emissions_boundary :string
# units :string
# assessment_date :date
# publication_date :date
# last_historical_year :integer
# trend_1_year :string
# trend_3_year :string
# trend_5_year :string
# emissions :jsonb
# created_at :datetime not null
# updated_at :datetime not null
# trend_source :string
# trend_year :integer
# recent_emission_level :float
# recent_emission_source :string
# recent_emission_year :integer
#
class ASCOR::Pathway < ApplicationRecord
include HasEmissions

Expand Down
1 change: 1 addition & 0 deletions app/models/bank_assessment_indicator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# text :text not null
# created_at :datetime not null
# updated_at :datetime not null
# comment :text
#
class BankAssessmentIndicator < ApplicationRecord
INDICATOR_TYPES = %w[area sub_area indicator sub_indicator].freeze
Expand Down
1 change: 1 addition & 0 deletions app/models/publication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# created_at :datetime not null
# updated_at :datetime not null
# author :string
# slug :text not null
#

class Publication < ApplicationRecord
Expand Down
30 changes: 30 additions & 0 deletions app/services/csv_export/ascor/assessment_indicators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module CSVExport
module ASCOR
class AssessmentIndicators
HEADERS = ['Id', 'Type', 'Code', 'Text', 'Units or response type'].freeze

def call
# BOM UTF-8
CSV.generate("\xEF\xBB\xBF") do |csv|
csv << HEADERS

assessment_indicators.each do |indicator|
csv << [
indicator.id,
indicator.indicator_type,
indicator.code,
indicator.text,
indicator.units_or_response_type
]
end
end
end

private

def assessment_indicators
@assessment_indicators ||= ::ASCOR::AssessmentIndicator.order(:id)
end
end
end
end
72 changes: 72 additions & 0 deletions app/services/csv_export/ascor/assessments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module CSVExport
module ASCOR
class Assessments
def call
CSV.generate("\xEF\xBB\xBF") do |csv|
csv << headers

assessments.each do |assessment|
csv << [
assessment.id,
assessment.assessment_date,
assessment.publication_date,
assessment.country_id,
assessment.country.name,
*answer_values_for(assessment),
*source_values_for(assessment),
*year_values_for(assessment),
assessment.notes
]
end
end
end

private

def headers
result = ['Id', 'Assessment date', 'Publication date', 'Country Id', 'Country']
result += assessment_indicators.reject { |i| i.indicator_type == 'pillar' || i.code.in?(%w[EP.1.a.i EP.1.a.ii]) }
.map { |i| "#{i.indicator_type} #{i.code}" }
result += assessment_indicators.select { |i| i.indicator_type.in?(%w[indicator metric]) }
.map { |i| "source #{i.indicator_type} #{i.code}" }
result += assessment_indicators.select { |i| i.indicator_type == 'metric' }
.map { |i| "year #{i.indicator_type} #{i.code}" }
result += ['Notes']
result
end

def answer_values_for(assessment)
assessment_indicators.reject { |i| i.indicator_type == 'pillar' || i.code.in?(%w[EP.1.a.i EP.1.a.ii]) }
.map do |indicator|
assessment_results[[assessment.id, indicator.id]]&.first&.answer
end
end

def source_values_for(assessment)
assessment_indicators.select { |i| i.indicator_type.in?(%w[indicator metric]) }
.map do |indicator|
assessment_results[[assessment.id, indicator.id]]&.first&.source
end
end

def year_values_for(assessment)
assessment_indicators.select { |i| i.indicator_type == 'metric' }
.map do |indicator|
assessment_results[[assessment.id, indicator.id]]&.first&.year
end
end

def assessments
@assessments ||= ::ASCOR::Assessment.joins(:country).includes(:country).order(:assessment_date, 'ascor_countries.name')
end

def assessment_results
@assessment_results ||= ::ASCOR::AssessmentResult.all.group_by { |r| [r.assessment_id, r.indicator_id] }
end

def assessment_indicators
@assessment_indicators ||= ::ASCOR::AssessmentIndicator.order(:id)
end
end
end
end
46 changes: 46 additions & 0 deletions app/services/csv_export/ascor/benchmarks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module CSVExport
module ASCOR
class Benchmarks
HEADERS = [
'Id',
'Country',
'Publication date',
'Emissions metric',
'Emissions boundary',
'Units',
'Benchmark type'
].freeze

def call
CSV.generate("\xEF\xBB\xBF") do |csv|
csv << (HEADERS + year_columns)

benchmarks.each do |benchmark|
csv << [
benchmark.id,
benchmark.country.name,
benchmark.publication_date,
benchmark.emissions_metric,
benchmark.emissions_boundary,
benchmark.units,
benchmark.benchmark_type,
year_columns.map do |year|
benchmark.emissions[year]
end
].flatten
end
end
end

private

def year_columns
@year_columns ||= benchmarks.flat_map(&:emissions_all_years).uniq.sort
end

def benchmarks
@benchmarks ||= ::ASCOR::Benchmark.joins(:country).includes(:country).order('ascor_countries.name')
end
end
end
end
39 changes: 39 additions & 0 deletions app/services/csv_export/ascor/countries.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module CSVExport
module ASCOR
class Countries
HEADERS = [
'Id',
'Name',
'Country ISO code',
'Region',
'World Bank lending group',
'International Monetary Fund fiscal monitor category',
'Type of Party to the United Nations Framework Convention on Climate Change'
].freeze

def call
CSV.generate("\xEF\xBB\xBF") do |csv|
csv << HEADERS

countries.each do |country|
csv << [
country.id,
country.name,
country.iso,
country.region,
country.wb_lending_group,
country.fiscal_monitor_category,
country.type_of_party
]
end
end
end

private

def countries
@countries ||= ::ASCOR::Country.order(:name)
end
end
end
end
Loading