Merge pull request #7691 from betagouv/7667-zone-millesime
7667 Prendre en compte les changements de ministères
This commit is contained in:
commit
a054a4d0f9
17 changed files with 330 additions and 55 deletions
|
@ -48,6 +48,6 @@ class ZoneDashboard < Administrate::BaseDashboard
|
|||
# across all pages of the admin dashboard.
|
||||
#
|
||||
def display_resource(zone)
|
||||
"Zone #{zone.label}"
|
||||
"Zone #{zone.current_label}"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
module ZoneHelper
|
||||
def grouped_options_for_zone
|
||||
def grouped_options_for_zone(date)
|
||||
collectivite = Zone.find_by(acronym: "COLLECTIVITE")
|
||||
{
|
||||
"--" => [[I18n.t('i_dont_know', scope: 'utils'), nil], [collectivite.label, collectivite.id]],
|
||||
I18n.t('ministeres', scope: 'zones') => (Zone.order(:label) - [collectivite]).map { |m| [m.label, m.id] }
|
||||
"--" => [
|
||||
[I18n.t('i_dont_know', scope: 'utils'), nil],
|
||||
[collectivite.label, collectivite.id]
|
||||
],
|
||||
I18n.t('ministeres', scope: 'zones') => (Zone.available_at(date) - [collectivite]).map { |m| [m.label_at(date), m.id] }
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -812,6 +812,10 @@ class Procedure < ApplicationRecord
|
|||
api_particulier_sources['mesri'].present?
|
||||
end
|
||||
|
||||
def published_or_created_at
|
||||
published_at || created_at
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def move_new_children_to_new_parent_coordinate(new_draft)
|
||||
|
|
|
@ -10,5 +10,23 @@
|
|||
#
|
||||
class Zone < ApplicationRecord
|
||||
validates :acronym, presence: true, uniqueness: true
|
||||
has_many :labels, -> { order(designated_on: :desc) }, class_name: 'ZoneLabel', inverse_of: :zone
|
||||
has_many :procedures, -> { order(published_at: :desc) }, inverse_of: :zone
|
||||
|
||||
def current_label
|
||||
labels.first.name
|
||||
end
|
||||
|
||||
def label_at(date)
|
||||
label = labels.where('designated_on < ?', date)&.first || labels.last
|
||||
label.name
|
||||
end
|
||||
|
||||
def available_at?(date)
|
||||
label_at(date) != 'Non attribué'
|
||||
end
|
||||
|
||||
def self.available_at(date)
|
||||
Zone.all.filter { |zone| zone.available_at?(date) }.sort_by { |zone| zone.label_at(date) }
|
||||
end
|
||||
end
|
||||
|
|
14
app/models/zone_label.rb
Normal file
14
app/models/zone_label.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: zone_labels
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# designated_on :date not null
|
||||
# name :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# zone_id :bigint not null
|
||||
#
|
||||
class ZoneLabel < ApplicationRecord
|
||||
belongs_to :zone
|
||||
end
|
|
@ -17,7 +17,7 @@
|
|||
= f.label :zone do
|
||||
= t('zone', scope: 'activerecord.attributes.procedure')
|
||||
%span.mandatory *
|
||||
= f.select :zone_id, grouped_options_for_zone
|
||||
= f.select :zone_id, grouped_options_for_zone(@procedure.published_or_created_at)
|
||||
|
||||
%h3.header-subsection Logo de la démarche
|
||||
= render Attachment::EditComponent.new(form: f, attached_file: @procedure.logo, direct_upload: true, user_can_destroy: true)
|
||||
|
|
|
@ -1,37 +1,58 @@
|
|||
ministeres:
|
||||
- MAA:
|
||||
label: "Ministère de l'Agriculture et de l'Alimentation"
|
||||
- '2022-05-20': "Ministère de l'Agriculture et de la Souveraineté alimentaire"
|
||||
- '2020-07-06': "Ministère de l'Agriculture et de l'Alimentation"
|
||||
- MC:
|
||||
label: "Ministère de la Culture"
|
||||
- '2020-07-06': "Ministère de la Culture"
|
||||
- MAS:
|
||||
label: "Ministère des Solidarités et de la Santé"
|
||||
- '2022-05-20': "Ministère de la Santé et de la Prévention"
|
||||
- '2020-07-06': "Ministère des Solidarités et de la Santé"
|
||||
- MSAPH:
|
||||
- '2022-05-20': "Ministère des Solidarités, de l'Autonomie et des personnes handicapées"
|
||||
- '2020-07-06': "Non attribué"
|
||||
- MTEI:
|
||||
label: "Ministère du Travail"
|
||||
- '2022-05-20': "Ministère du Travail, du Plein emploi et de l'Insertion"
|
||||
- '2020-07-06': "Ministère du Travail"
|
||||
- MEAE:
|
||||
label: "Ministère de l'Europe et des Affaires étrangères"
|
||||
- '2020-07-06': "Ministère de l'Europe et des Affaires étrangères"
|
||||
- MEF:
|
||||
label: "Ministère de l'Économie, des Finances et de la Relance"
|
||||
- '2022-05-20': "Ministère de l'Économie, des Finances et de la Souveraineté industrielle et numérique"
|
||||
- '2020-07-06': "Ministère de l'Économie, des Finances et de la Relance"
|
||||
- MJS:
|
||||
label: "Ministère de la Jeunesse et des Sports"
|
||||
- '2022-05-20': "Non attribué"
|
||||
- '2020-07-06': "Ministère de la Jeunesse et des Sports"
|
||||
- MSJO:
|
||||
- '2022-05-20': "Ministère des Sports et des Jeux olympiques et paralympiques"
|
||||
- '2020-07-06': "Non attribué"
|
||||
- MEN:
|
||||
label: "Ministère de l'Éducation nationale, de la Jeunesse et des Sports"
|
||||
- '2022-05-20': "Ministère de l'Éducation nationale et de la Jeunesse"
|
||||
- '2020-07-06': "Ministère de l'Éducation nationale, de la Jeunesse et des Sports"
|
||||
- ESR:
|
||||
label: "Ministère de l'Enseignement supérieur, de la Recherche et de l'Innovation"
|
||||
- '2022-05-20': "Ministère de l'Enseignement supérieur et de la Recherche"
|
||||
- '2020-07-06': "Ministère de l'Enseignement supérieur, de la Recherche et de l'Innovation"
|
||||
- MI:
|
||||
label: "Ministère de l'Intérieur"
|
||||
- '2022-05-20': "Ministère de l'Intérieur et des Outre-mer"
|
||||
- '2020-07-06': "Ministère de l'Intérieur"
|
||||
- MINARM:
|
||||
label: "Ministère des Armées"
|
||||
- '2020-07-06': "Ministère des Armées"
|
||||
- MJ:
|
||||
label: "Ministère de la Justice"
|
||||
- '2020-07-06': "Ministère de la Justice"
|
||||
- MTES:
|
||||
label: "Ministère de la Transition écologique"
|
||||
- '2022-05-20': "Ministère de la Transition écologique et de la Cohésion des territoires"
|
||||
- '2020-07-06': "Ministère de la Transition écologique"
|
||||
- MTE:
|
||||
- '2022-05-20': "Ministère de la Transition énergétique"
|
||||
- '2020-07-06': "Non attribué"
|
||||
- MCTRCT:
|
||||
label: "Ministère de la Cohésion des territoires et des Relations avec les collectivités territoriales"
|
||||
- '2022-05-20': "Non attribué"
|
||||
- '2020-07-06': "Ministère de la Cohésion des territoires et des Relations avec les collectivités territoriales"
|
||||
- PM:
|
||||
label: "Premier ministre"
|
||||
- '2020-07-06': "Premier ministre"
|
||||
- MER:
|
||||
label: "Ministère de la Mer"
|
||||
- '2022-05-20': "Non attribué"
|
||||
- '2020-07-06': "Ministère de la Mer"
|
||||
- MTFP:
|
||||
label: "Ministère de la Transformation et de la Fonction publiques"
|
||||
- '2020-07-06': "Ministère de la Transformation et de la Fonction publiques"
|
||||
- OM:
|
||||
label: "Ministère des Outre-mer"
|
||||
- '2022-05-20': "Non attribué"
|
||||
- '2020-07-06': "Ministère des Outre-mer"
|
||||
|
|
11
db/migrate/20220911134914_create_zone_labels.rb
Normal file
11
db/migrate/20220911134914_create_zone_labels.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
class CreateZoneLabels < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :zone_labels do |t|
|
||||
t.belongs_to :zone, null: false, foreign_key: true
|
||||
t.date :designated_on, null: false
|
||||
t.string :name, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
12
db/schema.rb
12
db/schema.rb
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2022_09_02_151920) do
|
||||
ActiveRecord::Schema.define(version: 2022_09_11_134914) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pgcrypto"
|
||||
|
@ -861,6 +861,15 @@ ActiveRecord::Schema.define(version: 2022_09_02_151920) do
|
|||
t.index ["procedure_id"], name: "index_without_continuation_mails_on_procedure_id"
|
||||
end
|
||||
|
||||
create_table "zone_labels", force: :cascade do |t|
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.date "designated_on", null: false
|
||||
t.string "name", null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
t.bigint "zone_id", null: false
|
||||
t.index ["zone_id"], name: "index_zone_labels_on_zone_id"
|
||||
end
|
||||
|
||||
create_table "zones", force: :cascade do |t|
|
||||
t.string "acronym", null: false
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
|
@ -922,4 +931,5 @@ ActiveRecord::Schema.define(version: 2022_09_02_151920) do
|
|||
add_foreign_key "trusted_device_tokens", "instructeurs"
|
||||
add_foreign_key "users", "users", column: "requested_merge_into_id"
|
||||
add_foreign_key "without_continuation_mails", "procedures"
|
||||
add_foreign_key "zone_labels", "zones"
|
||||
end
|
||||
|
|
28
lib/tasks/deployment/20220922151100_populate_zones.rake
Normal file
28
lib/tasks/deployment/20220922151100_populate_zones.rake
Normal file
|
@ -0,0 +1,28 @@
|
|||
namespace :after_party do
|
||||
desc 'Deployment task: populate_zones'
|
||||
task populate_zones: :environment do
|
||||
if Flipper.enabled? :zonage
|
||||
puts "Running deploy task 'populate_zones'"
|
||||
collectivite = Zone.find_or_create_by!(acronym: 'COLLECTIVITE')
|
||||
coll_label = collectivite.labels.find_or_initialize_by(designated_on: Date.parse('1977-07-30'))
|
||||
coll_label.update(name: 'Collectivité territoriale')
|
||||
|
||||
config = Psych.safe_load(File.read(Rails.root.join("config", "zones.yml")))
|
||||
config["ministeres"].each do |ministere|
|
||||
acronym = ministere.keys.first
|
||||
zone = Zone.find_or_create_by!(acronym: acronym)
|
||||
labels_a = ministere[acronym]
|
||||
labels_a.each do |label_h|
|
||||
designated_on = label_h.keys.first
|
||||
label = zone.labels.find_or_initialize_by(designated_on: designated_on)
|
||||
label.update(name: label_h[designated_on])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Update task as completed. If you remove the line below, the task will
|
||||
# run with every deploy (or every time you call after_party:run).
|
||||
AfterParty::TaskRecord
|
||||
.create version: AfterParty::TaskRecorder.new(__FILE__).timestamp
|
||||
end
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
namespace :zones do
|
||||
task populate_zones: :environment do
|
||||
puts "Running deploy task 'populate_zones'"
|
||||
|
||||
Zone.create!(acronym: 'COLLECTIVITE', label: 'Collectivité territoriale')
|
||||
config = Psych.safe_load(File.read(Rails.root.join("config", "zones.yml")))
|
||||
config["ministeres"].each do |ministere|
|
||||
acronym = ministere.keys.first
|
||||
Zone.create!(acronym: acronym, label: ministere["label"])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +1,14 @@
|
|||
FactoryBot.define do
|
||||
factory :zone do
|
||||
sequence(:acronym) { |n| "MA#{n}" }
|
||||
sequence(:label) { |n| "Ministère de l'Education Populaire #{n}" }
|
||||
transient do
|
||||
labels { [{ designated_on: '1981-05-08', name: "Ministère de l'Education Populaire" }] }
|
||||
end
|
||||
|
||||
after(:create) do |zone, evaluator|
|
||||
evaluator.labels.each do |label|
|
||||
zone.labels.create(designated_on: label[:designated_on], name: label[:name])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
describe '20220922151100_populate_zones' do
|
||||
let(:rake_task) { Rake::Task['after_party:populate_zones'] }
|
||||
subject(:run_task) do
|
||||
Flipper.enable :zonage
|
||||
rake_task.invoke
|
||||
end
|
||||
after(:each) do
|
||||
rake_task.reenable
|
||||
end
|
||||
|
||||
it 'populates zones' do
|
||||
run_task
|
||||
expect(Zone.find_by(acronym: 'PM').label).to eq "Premier ministre"
|
||||
expect(Zone.find_by(acronym: 'MTEI').labels.first.designated_on).to eq Date.parse('2022-05-20')
|
||||
expect(Zone.find_by(acronym: 'MTEI').labels.first.name).to eq "Ministère du Travail, du Plein emploi et de l'Insertion"
|
||||
expect(Zone.find_by(acronym: 'MTEI').labels.last.designated_on).to eq Date.parse('2020-07-06')
|
||||
expect(Zone.find_by(acronym: 'MTEI').labels.last.name).to eq "Ministère du Travail"
|
||||
end
|
||||
end
|
|
@ -1,14 +0,0 @@
|
|||
describe 'populate_zones' do
|
||||
let(:rake_task) { Rake::Task['zones:populate_zones'] }
|
||||
subject(:run_task) do
|
||||
rake_task.invoke
|
||||
end
|
||||
after(:each) do
|
||||
rake_task.reenable
|
||||
end
|
||||
|
||||
it 'populates zones' do
|
||||
run_task
|
||||
expect(Zone.find_by(acronym: 'PM').label).to eq "Premier ministre"
|
||||
end
|
||||
end
|
121
spec/models/zone_spec.rb
Normal file
121
spec/models/zone_spec.rb
Normal file
|
@ -0,0 +1,121 @@
|
|||
describe Zone do
|
||||
let(:now) { Time.zone.parse("2022-08-11") }
|
||||
before do
|
||||
Timecop.freeze(now)
|
||||
end
|
||||
|
||||
after do
|
||||
Timecop.return
|
||||
end
|
||||
|
||||
describe '#label' do
|
||||
let(:start_previous_government) { Date.parse('2020-07-06') }
|
||||
let(:start_last_government) { Date.parse('2022-05-20') }
|
||||
let(:zone) do
|
||||
create(:zone, labels: [
|
||||
{
|
||||
designated_on: start_previous_government,
|
||||
name: "Ministère de l'Économie, des Finances et de la Relance"
|
||||
},
|
||||
{
|
||||
designated_on: start_last_government,
|
||||
name: "Ministère de l'Économie, des Finances et de la Souveraineté industrielle et numérique"
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
it 'returns label for the current millesime' do
|
||||
expect(zone.current_label).to eq "Ministère de l'Économie, des Finances et de la Souveraineté industrielle et numérique"
|
||||
end
|
||||
|
||||
it 'returns label at specific date' do
|
||||
expect(zone.label_at(start_previous_government + 1.week)).to eq "Ministère de l'Économie, des Finances et de la Relance"
|
||||
expect(zone.label_at(start_last_government + 1.week)).to eq "Ministère de l'Économie, des Finances et de la Souveraineté industrielle et numérique"
|
||||
expect(zone.label_at(start_previous_government - 1.week)).to eq "Ministère de l'Économie, des Finances et de la Relance"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#available_at?" do
|
||||
let(:start_previous_government) { Date.parse('2020-07-06') }
|
||||
let(:start_last_government) { Date.parse('2022-05-20') }
|
||||
let(:start_futur_government) { Date.parse('2027-05-20') }
|
||||
let(:zone) do
|
||||
create(:zone, labels: [
|
||||
{
|
||||
designated_on: start_previous_government,
|
||||
name: "Ministère des Outre-mer"
|
||||
},
|
||||
{
|
||||
designated_on: start_last_government,
|
||||
name: "Non attribué"
|
||||
},
|
||||
{
|
||||
designated_on: start_futur_government,
|
||||
name: "Ministère des Territoires d'Outre-mer"
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
it "returns false if the zone does'nt exist at a specific date" do
|
||||
expect(zone.available_at?(start_last_government + 1.week)).to be_falsy
|
||||
end
|
||||
|
||||
it "returns true if the zone exist at a specific date" do
|
||||
expect(zone.available_at?(start_futur_government + 1.week)).to be_truthy
|
||||
expect(zone.available_at?(start_previous_government + 1.week)).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "#self.available_at?" do
|
||||
let(:start_previous_government) { Date.parse('2020-07-06') }
|
||||
let(:start_last_government) { Date.parse('2022-05-20') }
|
||||
let(:start_futur_government) { Date.parse('2027-05-20') }
|
||||
let(:om) do
|
||||
create(:zone, labels: [
|
||||
{
|
||||
designated_on: start_previous_government,
|
||||
name: "Ministère des Outre-mer"
|
||||
},
|
||||
{
|
||||
designated_on: start_last_government,
|
||||
name: "Non attribué"
|
||||
},
|
||||
{
|
||||
designated_on: start_futur_government,
|
||||
name: "Ministère des Territoires d'Outre-mer"
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
let!(:culture) do
|
||||
create(:zone, labels: [
|
||||
{
|
||||
designated_on: start_previous_government,
|
||||
name: "Ministère de la Culture"
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
let!(:om) do
|
||||
create(:zone, labels: [
|
||||
{
|
||||
designated_on: start_previous_government,
|
||||
name: "Ministère des Outre-mer"
|
||||
},
|
||||
{
|
||||
designated_on: start_last_government,
|
||||
name: "Non attribué"
|
||||
},
|
||||
{
|
||||
designated_on: start_futur_government,
|
||||
name: "Ministère des Territoires d'Outre-mer"
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
it 'returns only available zones at specific date' do
|
||||
expect(Zone.available_at(start_last_government + 1.day)).to eq [culture]
|
||||
expect(Zone.available_at(start_previous_government + 1.day)).to eq [culture, om]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +1,11 @@
|
|||
describe UpdateZoneToProceduresService do
|
||||
before(:each) do
|
||||
Rake::Task['zones:populate_zones'].invoke
|
||||
Flipper.enable :zonage
|
||||
Rake::Task['after_party:populate_zones'].invoke
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
Rake::Task['zones:populate_zones'].reenable
|
||||
Rake::Task['after_party:populate_zones'].reenable
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
|
|
|
@ -1,15 +1,58 @@
|
|||
describe 'administrateurs/procedures/edit.html.haml' do
|
||||
let(:logo) { fixture_file_upload('spec/fixtures/files/logo_test_procedure.png', 'image/png') }
|
||||
let(:procedure) { create(:procedure, logo: logo, lien_site_web: 'http://some.website') }
|
||||
let(:populate_zones_task) { Rake::Task['after_party:populate_zones'] }
|
||||
|
||||
before do
|
||||
assign(:procedure, procedure)
|
||||
render
|
||||
Flipper.enable(:zonage)
|
||||
populate_zones_task.invoke
|
||||
end
|
||||
|
||||
after do
|
||||
populate_zones_task.reenable
|
||||
end
|
||||
|
||||
context 'when procedure logo is present' do
|
||||
it 'display on the page' do
|
||||
assign(:procedure, procedure)
|
||||
render
|
||||
|
||||
expect(rendered).to have_selector('.procedure-logos')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when procedure has never been published' do
|
||||
before { Timecop.freeze(now) }
|
||||
after { Timecop.return }
|
||||
|
||||
let(:procedure) { create(:procedure, zone: Zone.find_by(acronym: 'MTEI')) }
|
||||
let(:now) { Time.zone.parse('18/05/2022') }
|
||||
|
||||
it 'displays zones with label available at the creation date' do
|
||||
assign(:procedure, procedure)
|
||||
render
|
||||
|
||||
expect(rendered).to have_content("Ministère du Travail")
|
||||
expect(rendered).not_to have_content("Ministère du Travail, du Plein emploi et de l'Insertion")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when procedure has been published' do
|
||||
before { Timecop.freeze(now) }
|
||||
after { Timecop.return }
|
||||
|
||||
let(:procedure) { create(:procedure, zone: Zone.find_by(acronym: 'MTEI')) }
|
||||
let(:now) { Time.zone.parse('18/05/2022') }
|
||||
|
||||
it 'displays zones with label available at the creation date' do
|
||||
Timecop.freeze(Time.zone.parse('22/05/2022')) do
|
||||
procedure.publish!
|
||||
end
|
||||
|
||||
assign(:procedure, procedure)
|
||||
render
|
||||
|
||||
expect(rendered).to have_content("Ministère du Travail, du Plein emploi et de l'Insertion")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue