From bed0426c3a97ba8fb8262412a463d47873bb5d25 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 1 Apr 2022 15:42:32 +0100 Subject: [PATCH 01/23] add EU Decisions endpoint for captive breeding --- .../api/v1/eu_decisions_controller.rb | 69 +++++++++++++++++++ config/routes.rb | 1 + 2 files changed, 70 insertions(+) create mode 100644 app/controllers/api/v1/eu_decisions_controller.rb diff --git a/app/controllers/api/v1/eu_decisions_controller.rb b/app/controllers/api/v1/eu_decisions_controller.rb new file mode 100644 index 000000000..b77978e2e --- /dev/null +++ b/app/controllers/api/v1/eu_decisions_controller.rb @@ -0,0 +1,69 @@ +class Api::V1::EuDecisionsController < ApplicationController + + # makes params available to the ActiveModel::Serializers + serialization_scope :view_context + + def index + @eu_decisions = eu_decision_search(sanitized_params) + render :json => @eu_decisions, + :each_serializer => CaptiveBreeding::EuDecisionSerializer + end + + private + + def permitted_params + params.permit(taxon_concept_ids: [], geo_entity_ids: []) + end + + def eu_decision_search(params) + list = EuDecision.from('api_eu_decisions_view eu_decisions'). + select(eu_decision_select_attrs). + joins('LEFT JOIN eu_suspensions_applicability_view v ON eu_decisions.id = v.id'). + order(<<-SQL + geo_entity_en->>'name' ASC, + start_date DESC + SQL + ) + + list = list.where("eu_decisions.taxon_concept_id IN (?)", params['taxon_concept_ids']) if params['taxon_concept_ids'].present? + list = list.where("eu_decisions.geo_entity_id IN (?)", params['geo_entity_ids']) if params['geo_entity_ids'].present? + + list.all + end + + def eu_decision_select_attrs + string = %{ + eu_decisions.notes, + eu_decisions.start_date, + v.original_start_date_formatted, + eu_decisions.is_current, + eu_decisions.geo_entity_id, + eu_decisions.start_event_id, + eu_decisions.term_id, + eu_decisions.source_id, + eu_decisions.eu_decision_type_id, + eu_decisions.term_id, + eu_decisions.source_id, + eu_decisions.nomenclature_note_en, + eu_decisions.nomenclature_note_fr, + eu_decisions.nomenclature_note_es, + eu_decision_type, + srg_history, + start_event, + end_event, + geo_entity_en, + taxon_concept, + term_en, + source_en + } + current_user ? "#{string},\n private_url" : string + end + + def sanitized_params + filters = permitted_params.inject({}) do |h, (k,v)| + h[k] = v.reject(&:empty?).map!(&:to_i) + h + end + filters + end +end diff --git a/config/routes.rb b/config/routes.rb index 809513809..3683970f2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -26,6 +26,7 @@ resources :sources, :only => [:index] resources :purposes, :only => [:index] resources :trade_plus_filters, only: :index + resources :eu_decisions, only: :index resources :documents do collection do get 'download_zip' From 362ce8de105997127cb516ae6dd7c4ebb884e621 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 1 Apr 2022 15:43:36 +0100 Subject: [PATCH 02/23] add eu decision serializer for captive breeding --- .../eu_decision_serializer.rb | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 app/serializers/captive_breeding/eu_decision_serializer.rb diff --git a/app/serializers/captive_breeding/eu_decision_serializer.rb b/app/serializers/captive_breeding/eu_decision_serializer.rb new file mode 100644 index 000000000..b6df872fc --- /dev/null +++ b/app/serializers/captive_breeding/eu_decision_serializer.rb @@ -0,0 +1,45 @@ +class CaptiveBreeding::EuDecisionSerializer < ActiveModel::Serializer + attributes :taxon_concept, :notes, { :start_date_formatted => :start_date }, + :is_current, :nomenclature_note_en, :nomenclature_note_fr, + :nomenclature_note_es, + :eu_decision_type, + :srg_history, + :geo_entity, + :start_event, + :source, + :term, + { :original_start_date_formatted => :original_start_date }, + :private_url + + def taxon_concept + object['taxon_concept'] + end + + def eu_decision_type + object['eu_decision_type'] + end + + def srg_history + object['srg_history'] + end + + def geo_entity + { 'id'=> object['geo_entity_id'] }.merge(object['geo_entity_en']) + end + + def start_event + object['start_event'] + end + + def source + object['source_en'] + end + + def term + object['term_en'] + end + + def private_url + scope.current_user ? object['private_url'] : nil + end +end From 774b86c52cea379e5f80701ab2b82c98bdbd5e1e Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 17 Jun 2022 21:56:28 +0100 Subject: [PATCH 03/23] feat: add method to calculate aggregated over time shipments total [WIP] --- .../trade/grouping/trade_plus_static.rb | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/modules/trade/grouping/trade_plus_static.rb b/lib/modules/trade/grouping/trade_plus_static.rb index 68a64b724..61ba5e092 100644 --- a/lib/modules/trade/grouping/trade_plus_static.rb +++ b/lib/modules/trade/grouping/trade_plus_static.rb @@ -242,6 +242,28 @@ def over_time_query SQL end + def aggregated_over_time_query + quantity_field = @country_ids.present? ? "#{entity_quantity}_reported_quantity" : "#{@reported_by}_reported_quantity" + + <<-SQL + SELECT ROW_TO_JSON(row) + FROM ( + SELECT JSON_AGG(JSON_BUILD_OBJECT('x', year, 'y', value) ORDER BY year) AS datapoints + FROM ( + SELECT year, ROUND(SUM(#{quantity_field}::FLOAT)) AS value + FROM #{shipments_table} + #{child_taxa_join} + WHERE #{@condition} AND #{quantity_field} IS NOT NULL AND #{country_condition} + AND #{child_taxa_condition} + GROUP BY year + #{quantity_condition(quantity_field)} + ORDER BY value DESC + #{limit} + ) t + ) row + SQL + end + def taxonomic_query(opts) quantity_field = @country_ids.present? ? "#{entity_quantity}_reported_quantity" : "#{@reported_by}_reported_quantity" taxonomic_level = opts[:taxonomic_level] || 'class' From ae5d71e55f9a1dc66550e3372e24fc4afb50042f Mon Sep 17 00:00:00 2001 From: lucacug Date: Thu, 23 Jun 2022 17:26:22 +0100 Subject: [PATCH 04/23] refactor: properly sanitise aggregated response and add todo comments --- lib/modules/trade/grouping/trade_plus_static.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/modules/trade/grouping/trade_plus_static.rb b/lib/modules/trade/grouping/trade_plus_static.rb index 61ba5e092..d17823a3d 100644 --- a/lib/modules/trade/grouping/trade_plus_static.rb +++ b/lib/modules/trade/grouping/trade_plus_static.rb @@ -17,6 +17,12 @@ def over_time_data sanitise_response_over_time_query(response) end + def aggregated_over_time_data + data = db.execute(aggregated_over_time_query) + response = data.map { |d| JSON.parse(d['row_to_json']) } + sanitise_response_aggregated_over_time_query(response) + end + def country_data db.execute(country_query) end @@ -29,6 +35,13 @@ def sanitise_response_over_time_query(response) response.partition { |value| value['id'] != 'unreported' }.reduce(:+) end + def sanitise_response_aggregated_over_time_query(response) + response.map do |value| + value['id'], value['name'] = "reported_by_#{@reported_by}", "reported_by_#{@reported_by}" if value['id'].nil? + end + response.partition { |value| value['id'] != 'unreported' }.reduce(:+) + end + def taxonomic_grouping(opts={}) data = db.execute(taxonomic_query(opts)) data.map { |d| JSON.parse(d['row_to_json']) } @@ -242,6 +255,8 @@ def over_time_query SQL end + + # TODO refactor to merge this method and the over_time one above together def aggregated_over_time_query quantity_field = @country_ids.present? ? "#{entity_quantity}_reported_quantity" : "#{@reported_by}_reported_quantity" From 724f018c2015cdc1d41e51c8b5d1a209f8306509 Mon Sep 17 00:00:00 2001 From: lucacug Date: Thu, 23 Jun 2022 17:27:07 +0100 Subject: [PATCH 05/23] feat: add aggregated overtime endpoint and routes --- app/controllers/api/v1/shipments_controller.rb | 11 +++++++++++ config/routes.rb | 1 + 2 files changed, 12 insertions(+) diff --git a/app/controllers/api/v1/shipments_controller.rb b/app/controllers/api/v1/shipments_controller.rb index 04cd38197..5c95a962b 100644 --- a/app/controllers/api/v1/shipments_controller.rb +++ b/app/controllers/api/v1/shipments_controller.rb @@ -75,6 +75,17 @@ def over_time_query render json: @over_time_data end + # TODO refactor to merge this method and the over_time one above together + def aggregated_over_time_query + # TODO Remember to implement permitted parameters here + query = @grouping_class.new(sanitized_attributes, params) + @aggregated_over_time_data = Rails.cache.fetch(['aggregated_over_time_data', params], expires_in: 1.week) do + query.aggregated_over_time_data + end + + render json: @aggregated_over_time_data + end + def download_data @download_data = Rails.cache.fetch(['download_data', params], expires_in: 1.week) do Trade::DownloadDataRetriever.dashboard_download(download_params).to_a diff --git a/config/routes.rb b/config/routes.rb index 809513809..e8eacc9e7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -39,6 +39,7 @@ get '/shipments/chart' => 'shipments#chart_query' get '/shipments/grouped' => 'shipments#grouped_query' get '/shipments/over_time' => 'shipments#over_time_query' + get '/shipments/aggregated_over_time' => 'shipments#aggregated_over_time_query' get '/shipments/country' => 'shipments#country_query' get '/shipments/search' => 'shipments#search_query' get '/shipments/download' => 'shipments#download_data' From 2ae827d5e688e9e26e5c2e87c64fa63aca51a70f Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 5 Aug 2022 11:15:42 +0100 Subject: [PATCH 06/23] feat: add document reference to eu decisions migration. EuDecision is a STI table so it wasn t possible to add the reference directly to the eu opinions, but this is managed via the model --- .../20220803152826_add_document_ref_to_eu_decisions.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20220803152826_add_document_ref_to_eu_decisions.rb diff --git a/db/migrate/20220803152826_add_document_ref_to_eu_decisions.rb b/db/migrate/20220803152826_add_document_ref_to_eu_decisions.rb new file mode 100644 index 000000000..010a6e140 --- /dev/null +++ b/db/migrate/20220803152826_add_document_ref_to_eu_decisions.rb @@ -0,0 +1,5 @@ +class AddDocumentRefToEuDecisions < ActiveRecord::Migration + def change + add_reference :eu_decisions, :document, index: true + end +end From 534143e5f023cbd63208f901cca7932ed3b2a2f8 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 5 Aug 2022 11:24:22 +0100 Subject: [PATCH 07/23] feat: add has many relation between eu opinions and document and add validation to make sure event and document are not selected together --- app/models/document.rb | 1 + app/models/eu_opinion.rb | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/app/models/document.rb b/app/models/document.rb index 4d9f2b02d..92a571a97 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -44,6 +44,7 @@ class Document < ActiveRecord::Base foreign_key: 'primary_language_document_id', dependent: :nullify has_many :citations, class_name: 'DocumentCitation', dependent: :destroy + has_many :eu_opinions has_and_belongs_to_many :tags, class_name: 'DocumentTag', join_table: 'document_tags_documents' validates :title, presence: true validates :date, presence: true diff --git a/app/models/eu_opinion.rb b/app/models/eu_opinion.rb index c0f7876a0..c6ac41c1f 100644 --- a/app/models/eu_opinion.rb +++ b/app/models/eu_opinion.rb @@ -27,5 +27,15 @@ # class EuOpinion < EuDecision + attr_accessible :document_id + + belongs_to :document + validates :start_date, presence: true + validate :event_or_document_presence + + def event_or_document_presence + return if start_event_id.nil? ^ document_id.nil? + errors.add(:base, "Select at least an Event or a Document, but not both") + end end From f1048cb35298bc83ef7f1a225a8d038deb8a24c7 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 5 Aug 2022 11:26:25 +0100 Subject: [PATCH 08/23] feat: retreive intersessional documents only. These might be further filtered down once we know which document type/s will be used for them --- app/controllers/admin/eu_opinions_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/admin/eu_opinions_controller.rb b/app/controllers/admin/eu_opinions_controller.rb index 6c671e9eb..e4cbe60ef 100644 --- a/app/controllers/admin/eu_opinions_controller.rb +++ b/app/controllers/admin/eu_opinions_controller.rb @@ -44,6 +44,8 @@ def load_lib_objects @ec_srgs = Event.where("type = 'EcSrg' OR type = 'EuRegulation' AND name IN ('No 338/97', 'No 938/97', 'No 750/2013')" ).order("effective_at DESC") + # this will only return docs not attached to any event (intersessional docs) + @documents = Document.where(event_id: nil) end def collection From 0662ec4f501730ea995a247c6bad34b390efd26f Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 5 Aug 2022 11:28:24 +0100 Subject: [PATCH 09/23] feat: add documents dropdown to eu opinion form and allow the regulation one to be left blank --- app/views/admin/eu_opinions/_form.html.erb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/views/admin/eu_opinions/_form.html.erb b/app/views/admin/eu_opinions/_form.html.erb index ef5cc0e52..f9927e9fb 100644 --- a/app/views/admin/eu_opinions/_form.html.erb +++ b/app/views/admin/eu_opinions/_form.html.erb @@ -17,7 +17,17 @@
<%= f.select :start_event_id, options_from_collection_for_select(@ec_srgs, :id, :name, @eu_opinion.start_event_id), - { }, :class => "select2" + { :include_blank => true }, :class => "select2" + %> +
+ + +
+ <%= f.label :document_id, "Intersessional Document", :class => 'control-label' %> +
+ <%= f.select :document_id, + options_from_collection_for_select(@documents, :id, :title, @eu_opinion.document_id), + { :include_blank => true }, { :class => "select2", :style => 'width: 440px' } %>
From d2df91790820ffee1404936d2de066626ae0e5f2 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 5 Aug 2022 12:06:11 +0100 Subject: [PATCH 10/23] fix: change intersessional dropdown label --- app/views/admin/eu_opinions/_form.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/eu_opinions/_form.html.erb b/app/views/admin/eu_opinions/_form.html.erb index f9927e9fb..839ffa1ac 100644 --- a/app/views/admin/eu_opinions/_form.html.erb +++ b/app/views/admin/eu_opinions/_form.html.erb @@ -23,7 +23,7 @@
- <%= f.label :document_id, "Intersessional Document", :class => 'control-label' %> + <%= f.label :document_id, "Intersessional Decision", :class => 'control-label' %>
<%= f.select :document_id, options_from_collection_for_select(@documents, :id, :title, @eu_opinion.document_id), From 4cc6071286311f164a9f11422bcbc7bb5c5f9b26 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 5 Aug 2022 12:07:26 +0100 Subject: [PATCH 11/23] fix: filter down the intersessional docs by comission notes type and order --- app/controllers/admin/eu_opinions_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/eu_opinions_controller.rb b/app/controllers/admin/eu_opinions_controller.rb index e4cbe60ef..a6232b181 100644 --- a/app/controllers/admin/eu_opinions_controller.rb +++ b/app/controllers/admin/eu_opinions_controller.rb @@ -44,8 +44,9 @@ def load_lib_objects @ec_srgs = Event.where("type = 'EcSrg' OR type = 'EuRegulation' AND name IN ('No 338/97', 'No 938/97', 'No 750/2013')" ).order("effective_at DESC") - # this will only return docs not attached to any event (intersessional docs) - @documents = Document.where(event_id: nil) + # this will only return intersessional docs + @documents = Document.where("event_id IS NULL AND type = 'Document::CommissionNotes'") + .order('date DESC, title') end def collection From 5be16134ab61a7f6150edc8975cf1b780fac8bf9 Mon Sep 17 00:00:00 2001 From: lucacug Date: Thu, 11 Aug 2022 10:30:32 +0100 Subject: [PATCH 12/23] feat: add intersessional doc reference to api eu decision sql view --- .../api_eu_decisions_view/20220808165846.sql | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 db/views/api_eu_decisions_view/20220808165846.sql diff --git a/db/views/api_eu_decisions_view/20220808165846.sql b/db/views/api_eu_decisions_view/20220808165846.sql new file mode 100644 index 000000000..e21d44669 --- /dev/null +++ b/db/views/api_eu_decisions_view/20220808165846.sql @@ -0,0 +1,139 @@ +SELECT +eu_decisions.id, +eu_decisions.type, +eu_decisions.taxon_concept_id, +ROW_TO_JSON( + ROW( + taxon_concept_id, + taxon_concepts.full_name, + taxon_concepts.author_year, + taxon_concepts.data->'rank_name' + )::api_taxon_concept +) AS taxon_concept, +eu_decisions.notes, +CASE + WHEN eu_decisions.type = 'EuOpinion' + THEN eu_decisions.start_date::DATE + WHEN eu_decisions.type = 'EuSuspension' + THEN start_event.effective_at::DATE +END AS start_date, +CASE + WHEN eu_decisions.type = 'EuOpinion' + THEN eu_decisions.is_current + WHEN eu_decisions.type = 'EuSuspension' + THEN + CASE + WHEN start_event.effective_at <= current_date AND start_event.is_current = true + AND (eu_decisions.end_event_id IS NULL OR end_event.effective_at > current_date) + THEN TRUE + ELSE + FALSE + END +END AS is_current, +eu_decisions.geo_entity_id, +ROW_TO_JSON( + ROW( + geo_entities.iso_code2, + geo_entities.name_en, + geo_entity_types.name + )::api_geo_entity +) AS geo_entity_en, +ROW_TO_JSON( + ROW( + geo_entities.iso_code2, + geo_entities.name_es, + geo_entity_types.name + )::api_geo_entity +) AS geo_entity_es, +ROW_TO_JSON( + ROW( + geo_entities.iso_code2, + geo_entities.name_fr, + geo_entity_types.name + )::api_geo_entity +) AS geo_entity_fr, +eu_decisions.start_event_id, +ROW_TO_JSON( + ROW( + start_event.name || CASE WHEN start_event.type = 'EcSrg' THEN ' Soc' ELSE '' END, + start_event.effective_at::DATE, + start_event.url + )::api_event +) AS start_event, +start_event.private_url AS private_url, +eu_decisions.end_event_id, +ROW_TO_JSON( + ROW( + end_event.name, + end_event.effective_at::DATE, + end_event.url + )::api_event +) AS end_event, +documents.id AS intersessional_decision_id, +eu_decisions.term_id, +ROW_TO_JSON( + ROW( + terms.code, + terms.name_en + )::api_trade_code +) AS term_en, +ROW_TO_JSON( + ROW( + terms.code, + terms.name_es + )::api_trade_code +) AS term_es, +ROW_TO_JSON( + ROW( + terms.code, + terms.name_fr + )::api_trade_code +) AS term_fr, +ROW_TO_JSON( + ROW( + sources.code, + sources.name_en + )::api_trade_code +) AS source_en, +ROW_TO_JSON( + ROW( + sources.code, + sources.name_es + )::api_trade_code +) AS source_es, +ROW_TO_JSON( + ROW( + sources.code, + sources.name_fr + )::api_trade_code +) AS source_fr, +eu_decisions.source_id, +eu_decisions.eu_decision_type_id, +ROW_TO_JSON( + ROW( + eu_decision_types.name, + eu_decision_types.tooltip, + eu_decision_types.decision_type + )::api_eu_decision_type +) AS eu_decision_type, +eu_decisions.srg_history_id, +ROW_TO_JSON( + ROW( + srg_histories.name, + srg_histories.tooltip + )::api_srg_history +) AS srg_history, +eu_decisions.nomenclature_note_en, +eu_decisions.nomenclature_note_fr, +eu_decisions.nomenclature_note_es +FROM eu_decisions +JOIN geo_entities ON geo_entities.id = eu_decisions.geo_entity_id +JOIN geo_entity_types ON geo_entities.geo_entity_type_id = geo_entity_types.id +JOIN taxon_concepts ON taxon_concepts.id = eu_decisions.taxon_concept_id +LEFT JOIN events AS start_event ON start_event.id = eu_decisions.start_event_id +LEFT JOIN events AS end_event ON end_event.id = eu_decisions.end_event_id +LEFT JOIN trade_codes terms ON terms.id = eu_decisions.term_id AND terms.type = 'Term' +LEFT JOIN trade_codes sources ON sources.id = eu_decisions.source_id AND sources.type = 'Source' +LEFT JOIN eu_decision_types ON eu_decision_types.id = eu_decisions.eu_decision_type_id +LEFT JOIN srg_histories ON srg_histories.id = eu_decisions.srg_history_id +LEFT JOIN documents ON documents.id = eu_decisions.document_id; From caf62675028d1970a1d35602f2002c7d6f3583f5 Mon Sep 17 00:00:00 2001 From: lucacug Date: Thu, 11 Aug 2022 10:30:55 +0100 Subject: [PATCH 13/23] feat: add migration to update api eu decision sql view --- ...d_intersessional_document_to_eu_decisions_view.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb diff --git a/db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb b/db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb new file mode 100644 index 000000000..5ffd5ab89 --- /dev/null +++ b/db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb @@ -0,0 +1,12 @@ +class AddIntersessionalDocumentToEuDecisionsView < ActiveRecord::Migration + def up + execute "DROP VIEW IF EXISTS api_eu_decisions_view" + execute "CREATE VIEW api_eu_decisions_view AS #{view_sql('20220808165846', 'api_eu_decisions_view')}" + + end + + def down + execute "DROP VIEW IF EXISTS api_eu_decisions_view" + execute "CREATE VIEW api_eu_decisions_view AS #{view_sql('20200807121747', 'api_eu_decisions_view')}" + end +end From 94c8d7642c5ce03ee94e38e8a4903f12decaa69f Mon Sep 17 00:00:00 2001 From: lucacug Date: Thu, 11 Aug 2022 10:37:00 +0100 Subject: [PATCH 14/23] feat: add intersessional doc reference to eu decision and taxon concept show serializer --- app/serializers/species/eu_decision_serializer.rb | 7 ++++++- .../species/show_taxon_concept_serializer_cites.rb | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/serializers/species/eu_decision_serializer.rb b/app/serializers/species/eu_decision_serializer.rb index 0725e7508..ed4680326 100644 --- a/app/serializers/species/eu_decision_serializer.rb +++ b/app/serializers/species/eu_decision_serializer.rb @@ -9,7 +9,8 @@ class Species::EuDecisionSerializer < ActiveModel::Serializer :source, :term, { :original_start_date_formatted => :original_start_date }, - :private_url + :private_url, + :intersessional_decision_id def eu_decision_type object['eu_decision_type'] @@ -38,4 +39,8 @@ def term def private_url scope.current_user ? object['private_url'] : nil end + + def intersessional_decision_id + scope.current_user ? object['intersessional_decision_id'] : nil + end end diff --git a/app/serializers/species/show_taxon_concept_serializer_cites.rb b/app/serializers/species/show_taxon_concept_serializer_cites.rb index 06de6edf3..09059bd85 100644 --- a/app/serializers/species/show_taxon_concept_serializer_cites.rb +++ b/app/serializers/species/show_taxon_concept_serializer_cites.rb @@ -149,7 +149,7 @@ def eu_decision_select_attrs '[' || (taxon_concept->>'rank')::TEXT || ' decision ' || (taxon_concept->>'full_name')::TEXT || ']' END AS subspecies_info } - scope.current_user ? "#{string},\n private_url" : string + scope.current_user ? "#{string},\n private_url, \n intersessional_decision_id" : string end def cites_listing_changes From 7231a6a9785cec0717a6d9887a9b31a27056fab3 Mon Sep 17 00:00:00 2001 From: lucacug Date: Thu, 11 Aug 2022 10:39:24 +0100 Subject: [PATCH 15/23] feat: add logic to display link or static text based on user session --- .../taxon_concept/_eu_decisions.handlebars | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars b/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars index 89682571a..ba8ef22b4 100644 --- a/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars +++ b/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars @@ -65,21 +65,30 @@ {{#if isSignedIn }} + {{#if decision.intersessional_decision_id}} + + Intersessional Decision + + {{/if}} {{#if decision.private_url}} {{decision.start_event.name}} {{else}} {{#if decision.start_event.url}} - + {{decision.start_event.name}} - + {{/if}} {{/if}} {{else}} - - {{decision.start_event.name}} - + {{#if decision.start_event.name }} + + {{decision.start_event.name}} + + {{else}} + Intersessional Decision + {{/if}} {{/if}} @@ -151,21 +160,30 @@ {{#if isSignedIn }} + {{#if decision.intersessional_decision_id}} + + Intersessional Decision + + {{/if}} {{#if decision.private_url}} {{decision.start_event.name}} {{else}} {{#if decision.start_event.url}} - + {{decision.start_event.name}} - + {{/if}} {{/if}} {{else}} - - {{decision.start_event.name}} - + {{#if decision.start_event.name }} + + {{decision.start_event.name}} + + {{else}} + Intersessional Decision + {{/if}} {{/if}} From fc06f7d8d71271431cd86e602a8e62311b0cc875 Mon Sep 17 00:00:00 2001 From: lucacug Date: Thu, 11 Aug 2022 11:55:57 +0100 Subject: [PATCH 16/23] reafactor: properly rename method after changes --- app/controllers/admin/api_usage_controller.rb | 2 +- app/models/api_request.rb | 2 +- spec/models/api_request_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/api_usage_controller.rb b/app/controllers/admin/api_usage_controller.rb index f8f5f36de..55c44a0e4 100644 --- a/app/controllers/admin/api_usage_controller.rb +++ b/app/controllers/admin/api_usage_controller.rb @@ -1,7 +1,7 @@ class Admin::ApiUsageController < Admin::AdminController def index @recent_requests = ApiRequest.recent_requests - @users_by_activity = ApiRequest.top_5_most_active_users + @users_by_activity = ApiRequest.top_50_most_active_users end def show diff --git a/app/models/api_request.rb b/app/models/api_request.rb index 1a3b6169d..a49d2fdd7 100644 --- a/app/models/api_request.rb +++ b/app/models/api_request.rb @@ -30,7 +30,7 @@ class ApiRequest < ActiveRecord::Base RESPONSE_STATUSES = [200, 400, 401, 404, 422, 500] CONTROLLERS = ['taxon_concepts', 'distributions', 'cites_legislation', 'eu_legislation', 'references'] - def self.top_5_most_active_users + def self.top_50_most_active_users subquery = self.recent.select( [ :user_id, diff --git a/spec/models/api_request_spec.rb b/spec/models/api_request_spec.rb index 1ff7edb04..e93e33ea8 100644 --- a/spec/models/api_request_spec.rb +++ b/spec/models/api_request_spec.rb @@ -47,9 +47,9 @@ ) end - describe :top_5_most_active_users do + describe :top_50_most_active_users do subject { - ApiRequest.top_5_most_active_users + ApiRequest.top_50_most_active_users } specify { expect(subject.first.user_id).to eq(api_user.id) From a0d444a6a45193593dc7843473498ae718014807 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 19 Aug 2022 11:41:14 +0100 Subject: [PATCH 17/23] typo: lower case d of intersessional decision --- .../templates/taxon_concept/_eu_decisions.handlebars | 8 ++++---- app/views/admin/eu_opinions/_form.html.erb | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars b/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars index ba8ef22b4..754da8b2d 100644 --- a/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars +++ b/app/assets/javascripts/species/templates/taxon_concept/_eu_decisions.handlebars @@ -67,7 +67,7 @@ {{#if isSignedIn }} {{#if decision.intersessional_decision_id}} - Intersessional Decision + Intersessional decision {{/if}} {{#if decision.private_url}} @@ -87,7 +87,7 @@ {{decision.start_event.name}} {{else}} - Intersessional Decision + Intersessional decision {{/if}} {{/if}} @@ -162,7 +162,7 @@ {{#if isSignedIn }} {{#if decision.intersessional_decision_id}} - Intersessional Decision + Intersessional decision {{/if}} {{#if decision.private_url}} @@ -182,7 +182,7 @@ {{decision.start_event.name}} {{else}} - Intersessional Decision + Intersessional decision {{/if}} {{/if}} diff --git a/app/views/admin/eu_opinions/_form.html.erb b/app/views/admin/eu_opinions/_form.html.erb index 839ffa1ac..9c3706967 100644 --- a/app/views/admin/eu_opinions/_form.html.erb +++ b/app/views/admin/eu_opinions/_form.html.erb @@ -23,7 +23,7 @@
- <%= f.label :document_id, "Intersessional Decision", :class => 'control-label' %> + <%= f.label :document_id, "Intersessional decision", :class => 'control-label' %>
<%= f.select :document_id, options_from_collection_for_select(@documents, :id, :title, @eu_opinion.document_id), From 67cbe4daa46b8ba33eaaf0f7023631a03107ad78 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 19 Aug 2022 12:29:03 +0100 Subject: [PATCH 18/23] feat: add intersessional decision in the download and consolidate migrations --- ...sessional_document_to_eu_decisions_view.rb | 12 --- ...essional_decisions_to_eu_decisions_view.rb | 17 ++++ db/views/eu_decisions_view/20220819120523.sql | 90 +++++++++++++++++++ 3 files changed, 107 insertions(+), 12 deletions(-) delete mode 100644 db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb create mode 100644 db/migrate/20220819121517_add_intersessional_decisions_to_eu_decisions_view.rb create mode 100644 db/views/eu_decisions_view/20220819120523.sql diff --git a/db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb b/db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb deleted file mode 100644 index 5ffd5ab89..000000000 --- a/db/migrate/20220809103092_add_intersessional_document_to_eu_decisions_view.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AddIntersessionalDocumentToEuDecisionsView < ActiveRecord::Migration - def up - execute "DROP VIEW IF EXISTS api_eu_decisions_view" - execute "CREATE VIEW api_eu_decisions_view AS #{view_sql('20220808165846', 'api_eu_decisions_view')}" - - end - - def down - execute "DROP VIEW IF EXISTS api_eu_decisions_view" - execute "CREATE VIEW api_eu_decisions_view AS #{view_sql('20200807121747', 'api_eu_decisions_view')}" - end -end diff --git a/db/migrate/20220819121517_add_intersessional_decisions_to_eu_decisions_view.rb b/db/migrate/20220819121517_add_intersessional_decisions_to_eu_decisions_view.rb new file mode 100644 index 000000000..e81f1bce5 --- /dev/null +++ b/db/migrate/20220819121517_add_intersessional_decisions_to_eu_decisions_view.rb @@ -0,0 +1,17 @@ +class AddIntersessionalDecisionsToEuDecisionsView < ActiveRecord::Migration + def up + execute "DROP VIEW IF EXISTS api_eu_decisions_view" + execute "CREATE VIEW api_eu_decisions_view AS #{view_sql('20220808165846', 'api_eu_decisions_view')}" + + execute "DROP VIEW IF EXISTS eu_decisions_view" + execute "CREATE VIEW eu_decisions_view AS #{view_sql('20220819120523', 'eu_decisions_view')}" + end + + def down + execute "DROP VIEW IF EXISTS api_eu_decisions_view" + execute "CREATE VIEW api_eu_decisions_view AS #{view_sql('20200807121747', 'api_eu_decisions_view')}" + + execute "DROP VIEW IF EXISTS eu_decisions_view" + execute "CREATE VIEW eu_decisions_view AS #{view_sql('20200514150717', 'eu_decisions_view')}" + end +end diff --git a/db/views/eu_decisions_view/20220819120523.sql b/db/views/eu_decisions_view/20220819120523.sql new file mode 100644 index 000000000..5e0bf6eef --- /dev/null +++ b/db/views/eu_decisions_view/20220819120523.sql @@ -0,0 +1,90 @@ +SELECT + taxon_concept_id, + taxon_concepts.taxonomic_position, + (taxon_concepts.data->'kingdom_id')::INT AS kingdom_id, + (taxon_concepts.data->'phylum_id')::INT AS phylum_id, + (taxon_concepts.data->'class_id')::INT AS class_id, + (taxon_concepts.data->'order_id')::INT AS order_id, + (taxon_concepts.data->'family_id')::INT AS family_id, + taxon_concepts.data->'kingdom_name' AS kingdom_name, + taxon_concepts.data->'phylum_name' AS phylum_name, + taxon_concepts.data->'class_name' AS class_name, + taxon_concepts.data->'order_name' AS order_name, + taxon_concepts.data->'family_name' AS family_name, + taxon_concepts.data->'genus_name' AS genus_name, + LOWER(taxon_concepts.data->'species_name') AS species_name, + LOWER(taxon_concepts.data->'subspecies_name') AS subspecies_name, + taxon_concepts.full_name AS full_name, + taxon_concepts.data->'rank_name' AS rank_name, + eu_decisions.start_date, + TO_CHAR(eu_decisions.start_date, 'DD/MM/YYYY') AS start_date_formatted, + t.original_start_date, + TO_CHAR(t.original_start_date, 'DD/MM/YYYY') AS original_start_date_formatted, + geo_entity_id, + geo_entities.name_en AS party, + CASE + WHEN eu_decision_types.name ~* '^i+\)' + THEN '(No opinion) ' || eu_decision_types.name + ELSE eu_decision_types.name + END AS decision_type_for_display, + eu_decision_types.decision_type AS decision_type, + srg_histories.name AS srg_history, + sources.name_en AS source_name, + sources.code || ' - ' || sources.name_en AS source_code_and_name, + terms.name_en AS term_name, + eu_decisions.notes, + CASE + WHEN start_event.name IS NULL + THEN 'Intersessional decision' + ELSE start_event.name + END AS start_event_name, + CASE + WHEN ( + eu_decisions.type = 'EuOpinion' AND eu_decisions.is_current + ) + OR ( + eu_decisions.type = 'EuSuspension' + AND start_event.effective_at < current_date + AND start_event.is_current = true + AND (eu_decisions.end_event_id IS NULL OR end_event.effective_at > current_date) + ) + THEN TRUE + ELSE FALSE + END AS is_valid, + CASE + WHEN ( + eu_decisions.type = 'EuOpinion' AND eu_decisions.is_current + ) + OR ( + eu_decisions.type = 'EuSuspension' + AND start_event.effective_at < current_date + AND start_event.is_current = true + AND (eu_decisions.end_event_id IS NULL OR end_event.effective_at > current_date) + ) + THEN 'Valid' + ELSE 'Not Valid' + END AS is_valid_for_display, + CASE + WHEN eu_decisions.type = 'EuOpinion' + THEN eu_decisions.start_date + WHEN eu_decisions.type = 'EuSuspension' + THEN start_event.effective_at + END AS ordering_date, + CASE + WHEN LENGTH(eu_decisions.notes) > 0 THEN strip_tags(eu_decisions.notes) + ELSE '' + END + || CASE + WHEN LENGTH(eu_decisions.nomenclature_note_en) > 0 THEN E'\n' || strip_tags(eu_decisions.nomenclature_note_en) + ELSE '' + END AS full_note_en +FROM eu_decisions +LEFT JOIN eu_decision_types ON eu_decision_types.id = eu_decisions.eu_decision_type_id -- Eu Decision Type can be empty now +JOIN taxon_concepts ON taxon_concepts.id = eu_decisions.taxon_concept_id +LEFT JOIN srg_histories ON srg_histories.id = eu_decisions.srg_history_id +LEFT JOIN events AS start_event ON start_event.id = eu_decisions.start_event_id +LEFT JOIN events AS end_event ON end_event.id = eu_decisions.end_event_id +LEFT JOIN geo_entities ON geo_entities.id = eu_decisions.geo_entity_id +LEFT JOIN trade_codes sources ON sources.type = 'Source' AND sources.id = eu_decisions.source_id +LEFT JOIN trade_codes terms ON terms.type = 'Term' AND terms.id = eu_decisions.term_id +LEFT JOIN eu_suspensions_applicability_view t ON t.id = eu_decisions.id; From 9e92681459468fa26b9a83110e3c49573f3b5293 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 19 Aug 2022 14:31:51 +0100 Subject: [PATCH 19/23] spec: fix broken spec adding the event or document to the eu_opinions and cover intersessional doc cases --- .../admin/eu_opinions_controller_spec.rb | 163 +++++++++++++++--- spec/factories/documents.rb | 3 + 2 files changed, 145 insertions(+), 21 deletions(-) diff --git a/spec/controllers/admin/eu_opinions_controller_spec.rb b/spec/controllers/admin/eu_opinions_controller_spec.rb index 75e6162eb..db3c8fc65 100644 --- a/spec/controllers/admin/eu_opinions_controller_spec.rb +++ b/spec/controllers/admin/eu_opinions_controller_spec.rb @@ -5,6 +5,7 @@ before do @taxon_concept = create(:taxon_concept) + @eu_regulation = create(:ec_srg) end describe "GET index" do @@ -37,18 +38,40 @@ @eu_decision_type = create(:eu_decision_type) @srg_history = create(:srg_history) end - it "redirects to the EU Opinions index" do - post :create, - eu_opinion: { - eu_decision_type_id: @eu_decision_type.id, - srg_history_id: @srg_history.id, - start_date: Date.today, - geo_entity_id: create( - :geo_entity, geo_entity_type_id: country_geo_entity_type.id - ) - }, - taxon_concept_id: @taxon_concept.id - response.should redirect_to(admin_taxon_concept_eu_opinions_url(@taxon_concept.id)) + context "when intersessional document is present" do + before do + @document = create(:commission_note) + end + it "redirects to the EU Opinions index" do + post :create, + eu_opinion: { + eu_decision_type_id: @eu_decision_type.id, + srg_history_id: @srg_history.id, + start_date: Date.today, + document_id: @document.id, + geo_entity_id: create( + :geo_entity, geo_entity_type_id: country_geo_entity_type.id + ) + }, + taxon_concept_id: @taxon_concept.id + response.should redirect_to(admin_taxon_concept_eu_opinions_url(@taxon_concept)) + end + end + context "when event is present" do + it "redirects to the EU Opinions index" do + post :create, + eu_opinion: { + eu_decision_type_id: @eu_decision_type.id, + srg_history_id: @srg_history.id, + start_date: Date.today, + start_event_id: @eu_regulation.id, + geo_entity_id: create( + :geo_entity, geo_entity_type_id: country_geo_entity_type.id + ) + }, + taxon_concept_id: @taxon_concept.id + response.should redirect_to(admin_taxon_concept_eu_opinions_url(@taxon_concept)) + end end end @@ -65,16 +88,17 @@ before(:each) do @eu_opinion = create( :eu_opinion, - taxon_concept_id: @taxon_concept.id + taxon_concept_id: @taxon_concept.id, + start_event_id: @eu_regulation.id ) end it "renders the edit template" do - get :edit, id: @eu_opinion.id, taxon_concept_id: @taxon_concept.id + get :edit, id: @eu_opinion.id, taxon_concept_id: @taxon_concept.id, start_event_id: @eu_regulation.id response.should render_template('edit') end it "assigns @geo_entities" do territory = create(:geo_entity, geo_entity_type_id: territory_geo_entity_type.id) - get :edit, id: @eu_opinion.id, taxon_concept_id: @taxon_concept.id + get :edit, id: @eu_opinion.id, taxon_concept_id: @taxon_concept.id, start_event_id: @eu_regulation.id assigns(:geo_entities).should include(territory) end end @@ -83,10 +107,12 @@ before(:each) do @eu_opinion = create( :eu_opinion, - taxon_concept_id: @taxon_concept.id + taxon_concept_id: @taxon_concept.id, + start_event_id: @eu_regulation.id ) @eu_decision_type = create(:eu_decision_type) @srg_history = create(:srg_history) + @document = create(:commission_note) end context "when successful" do @@ -94,7 +120,8 @@ it "renders taxon_concepts EU Opinions page" do put :update, eu_opinion: { - eu_decision_type_id: @eu_decision_type.id + eu_decision_type_id: @eu_decision_type.id, + start_event_id: @eu_regulation.id }, id: @eu_opinion.id, taxon_concept_id: @taxon_concept.id @@ -105,11 +132,43 @@ end context "when eu decision type is not present" do + it "renders taxon_concepts EU Opinions page" do + put :update, + eu_opinion: { + eu_decision_type_id: nil, + srg_history_id: @srg_history.id, + start_event_id: @eu_regulation.id + }, + id: @eu_opinion.id, + taxon_concept_id: @taxon_concept.id + response.should redirect_to( + admin_taxon_concept_eu_opinions_url(@taxon_concept) + ) + end + end + + context "when event is present" do it "renders taxon_concepts EU Opinions page" do put :update, eu_opinion: { - eu_decision_type_id: nil, - srg_history_id: @srg_history.id + eu_decision_type_id: @eu_decision_type.id, + start_event_id: @eu_regulation.id + }, + id: @eu_opinion.id, + taxon_concept_id: @taxon_concept.id + response.should redirect_to( + admin_taxon_concept_eu_opinions_url(@taxon_concept) + ) + end + end + + context "when event is not present" do + it "renders taxon_concepts EU Opinions page" do + put :update, + eu_opinion: { + eu_decision_type_id: @eu_decision_type.id, + start_event_id: nil, + document_id: @document.id }, id: @eu_opinion.id, taxon_concept_id: @taxon_concept.id @@ -126,6 +185,7 @@ put :update, eu_opinion: { eu_decision_type_id: @eu_decision_type.id, + start_event_id: @eu_regulation.id, start_date: nil }, id: @eu_opinion.id, @@ -140,6 +200,7 @@ eu_opinion: { eu_decision_type_id: nil, srg_history_id: @srg_history.id, + start_event_id: @eu_regulation.id, start_date: nil }, id: @eu_opinion.id, @@ -162,18 +223,78 @@ response.should render_template('new') end end + + context "when event is present" do + it "renders new" do + put :update, + eu_opinion: { + eu_decision_type_id: @eu_decision_type.id, + start_event_id: @eu_regulation.id, + start_date: nil + }, + id: @eu_opinion.id, + taxon_concept_id: @taxon_concept.id + response.should render_template('new') + end + end + + context "when event is not present" do + it "renders new" do + put :update, + eu_opinion: { + eu_decision_type_id: @eu_decision_type.id, + start_event_id: nil, + document_id: @document.id, + start_date: nil + }, + id: @eu_opinion.id, + taxon_concept_id: @taxon_concept.id + response.should render_template('new') + end + end + + context "when both event and intersessional doc are empty" do + it "renders new" do + put :update, + eu_opinion: { + eu_decision_type_id: @eu_decision_type.id, + start_event_id: nil, + document_id: nil, + start_date: nil + }, + id: @eu_opinion.id, + taxon_concept_id: @taxon_concept.id + response.should render_template('new') + end + end + + context "when both event and intersessional doc are present" do + it "renders new" do + put :update, + eu_opinion: { + eu_decision_type_id: @eu_decision_type.id, + start_event_id: @eu_regulation.id, + document_id: @document.id, + start_date: nil + }, + id: @eu_opinion.id, + taxon_concept_id: @taxon_concept.id + response.should render_template('new') + end + end end describe "DELETE destroy" do before(:each) do @eu_opinion = create( :eu_opinion, - taxon_concept_id: @taxon_concept.id + taxon_concept_id: @taxon_concept.id, + start_event_id: @eu_regulation.id ) end it "redirects after delete" do delete :destroy, id: @eu_opinion.id, - taxon_concept_id: @taxon_concept.id + taxon_concept_id: @taxon_concept.id, start_event_id: @eu_regulation.id response.should redirect_to( admin_taxon_concept_eu_opinions_url(@taxon_concept) ) diff --git a/spec/factories/documents.rb b/spec/factories/documents.rb index 42641f759..7ff3ff966 100644 --- a/spec/factories/documents.rb +++ b/spec/factories/documents.rb @@ -14,6 +14,9 @@ factory :proposal, class: Document::Proposal do type 'Document::Proposal' end + factory :commission_note, class: Document::CommissionNotes do + type 'Document::CommissionNotes' + end end factory :document_citation do From 969c13ffa6b744dd3d77d2ea449065b698dc2e25 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 19 Aug 2022 14:54:12 +0100 Subject: [PATCH 20/23] spec: fix eu opinions model spec. This spec is far from being comprehensive and doesnt include context for decision type vs srg history nor event vs intersessional decision. TODO add more context into this spec --- spec/models/eu_opinion_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/models/eu_opinion_spec.rb b/spec/models/eu_opinion_spec.rb index 0b48b758b..0252f1cbb 100644 --- a/spec/models/eu_opinion_spec.rb +++ b/spec/models/eu_opinion_spec.rb @@ -63,7 +63,10 @@ end context "when valid" do - let(:eu_opinion) { build(:eu_opinion) } + before do + @eu_regulation = create(:ec_srg) + end + let(:eu_opinion) { build(:eu_opinion, start_event: @eu_regulation) } specify { eu_opinion.should be_valid } end From ffcb06c2ae5b0cc627003b82eb1deb75ec820409 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 19 Aug 2022 15:03:52 +0100 Subject: [PATCH 21/23] spec: fix full reassignment nomenclature change spec when eu opinions present --- spec/models/nomenclature_change/full_reassignment_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/models/nomenclature_change/full_reassignment_spec.rb b/spec/models/nomenclature_change/full_reassignment_spec.rb index 77f763a3e..942f98b91 100644 --- a/spec/models/nomenclature_change/full_reassignment_spec.rb +++ b/spec/models/nomenclature_change/full_reassignment_spec.rb @@ -33,7 +33,8 @@ context 'when EU Opinions present' do before(:each) do - create(:eu_opinion, taxon_concept: old_tc) + @eu_regulation = create(:ec_srg) + create(:eu_opinion, taxon_concept: old_tc, start_event: @eu_regulation) subject.process end specify { expect(new_tc.eu_opinions.count).to eq(1) } From 4d3ca972af85e3b50e096481060ac799a5ce06d8 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 19 Aug 2022 15:20:32 +0100 Subject: [PATCH 22/23] spec: fix destroy taxon concept spec when eu opinions attached --- spec/models/taxon_concept/destroy_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/taxon_concept/destroy_spec.rb b/spec/models/taxon_concept/destroy_spec.rb index 5e73e3dc0..87c9103ad 100644 --- a/spec/models/taxon_concept/destroy_spec.rb +++ b/spec/models/taxon_concept/destroy_spec.rb @@ -48,7 +48,7 @@ specify { @taxon_concept.destroy.should be_falsey } end context "when EU opinions" do - before(:each) { create(:eu_opinion, :taxon_concept => @taxon_concept) } + before(:each) { create(:eu_opinion, :taxon_concept => @taxon_concept, start_event: create(:ec_srg)) } specify { @taxon_concept.destroy.should be_falsey } end context "when EU suspensions" do From 131718bda3b0f5e44e13abdcf5ea2aef19f2eaf1 Mon Sep 17 00:00:00 2001 From: lucacug Date: Fri, 19 Aug 2022 22:09:21 +0100 Subject: [PATCH 23/23] chore: update CHANGELOG with intersessional decision work --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f630b96fa..fdab1903a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ +### 1.8.0 + +**Intersessional decisions** + +* Make direct association between Eu Decisions and Documents +* Add validation on Eu Opinions (Event or Intersessional doc, not both at least one of the two) +* Update Eu Decisions SQL views +* Update FE to display link to Intersessional doc or static text based on user session + ### 1.7.1 **CITES Trade DB** -* Update to version 2021.1(replace zip file on the server, update ENV var, text updates) +* Update to version 2022.1(replace zip file on the server, update ENV var, text updates) ### 1.7.0