Merge pull request #9621 from mfo/US/type-de-champs-ej
amelioration(chorus): ETQ admin, je peux ajouter un type de champ EngagementJuridique
This commit is contained in:
commit
b61fa88fe0
34 changed files with 351 additions and 91 deletions
|
@ -0,0 +1,2 @@
|
|||
class EditableChamp::EngagementJuridiqueComponent < EditableChamp::EditableChampBaseComponent
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
en:
|
|
@ -0,0 +1 @@
|
|||
= @form.text_field(:value, input_opts(id: @champ.input_id, required: @champ.required?, aria: { describedby: @champ.describedby_id }))
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
fr:
|
|
@ -3,13 +3,40 @@ class Procedure::ChorusFormComponent < ApplicationComponent
|
|||
|
||||
def initialize(procedure:)
|
||||
@procedure = procedure
|
||||
@chorus_configuration = @procedure.chorus_configuration
|
||||
end
|
||||
|
||||
def map_attribute_to_autocomplete_endpoint
|
||||
{
|
||||
centre_de_coup: data_sources_search_centre_couts_path,
|
||||
centre_de_cout: data_sources_search_centre_couts_path,
|
||||
domaine_fonctionnel: data_sources_search_domaine_fonct_path,
|
||||
referentiel_de_programmation: data_sources_search_ref_programmation_path
|
||||
}
|
||||
end
|
||||
|
||||
def format_displayed_value(attribute_name)
|
||||
case attribute_name
|
||||
when :centre_de_cout
|
||||
ChorusConfiguration.format_centre_de_cout_label(@chorus_configuration.centre_de_cout)
|
||||
when :domaine_fonctionnel
|
||||
ChorusConfiguration.format_domaine_fonctionnel_label(@chorus_configuration.domaine_fonctionnel)
|
||||
when :referentiel_de_programmation
|
||||
ChorusConfiguration.format_ref_programmation_label(@chorus_configuration.referentiel_de_programmation)
|
||||
else
|
||||
raise 'unknown attribute_name'
|
||||
end
|
||||
end
|
||||
|
||||
def format_hidden_value(attribute_name)
|
||||
case attribute_name
|
||||
when :centre_de_cout
|
||||
@chorus_configuration.centre_de_cout.to_json
|
||||
when :domaine_fonctionnel
|
||||
@chorus_configuration.domaine_fonctionnel.to_json
|
||||
when :referentiel_de_programmation
|
||||
@chorus_configuration.referentiel_de_programmation.to_json
|
||||
else
|
||||
raise 'unknown attribute_name'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
= form_for([procedure, procedure.chorus_configuration],url: admin_procedure_chorus_path(procedure), method: :put) do |f|
|
||||
= form_for([procedure, @chorus_configuration],url: admin_procedure_chorus_path(procedure), method: :put) do |f|
|
||||
- map_attribute_to_autocomplete_endpoint.map do |chorus_configuration_attribute, datasource_endpoint|
|
||||
- label_class_name = "#{chorus_configuration_attribute}-label"
|
||||
- label_id = "#{chorus_configuration_attribute}-label"
|
||||
.fr-select-group
|
||||
= f.label chorus_configuration_attribute, class: 'fr-label', id: label_class_name
|
||||
= render Dsfr::ComboboxComponent.new form: f, name: :chorus_configuration_attribute, url: datasource_endpoint, selected: procedure.chorus_configuration.format_displayed_value(chorus_configuration_attribute), id: chorus_configuration_attribute, class: 'fr-select', describedby: label_class_name do
|
||||
= f.hidden_field chorus_configuration_attribute, data: { value_slot: 'data' }, value: procedure.chorus_configuration.format_hidden_value(chorus_configuration_attribute)
|
||||
= f.label chorus_configuration_attribute, class: 'fr-label', id: label_id
|
||||
= render Dsfr::ComboboxComponent.new form: f,
|
||||
url: datasource_endpoint,
|
||||
selected: format_displayed_value(chorus_configuration_attribute),
|
||||
id: chorus_configuration_attribute,
|
||||
class: 'fr-select',
|
||||
describedby: label_id,
|
||||
name: :chorus_configuration_attribute do
|
||||
= f.hidden_field chorus_configuration_attribute, data: { value_slot: 'data' }, value: format_hidden_value(chorus_configuration_attribute)
|
||||
|
||||
= f.submit "Enregister", class: 'fr-btn'
|
||||
|
|
|
@ -63,6 +63,7 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent
|
|||
.filter(&method(:filter_type_champ))
|
||||
.filter(&method(:filter_featured_type_champ))
|
||||
.filter(&method(:filter_block_type_champ))
|
||||
.filter(&method(:filter_public_or_private_only_type_champ))
|
||||
.group_by { TypeDeChamp::TYPE_DE_CHAMP_TO_CATEGORIE.fetch(_1.to_sym) }
|
||||
.sort_by { |k, _v| TypeDeChamp::CATEGORIES.find_index(k) }
|
||||
.to_h do |cat, tdc|
|
||||
|
@ -91,6 +92,14 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent
|
|||
!coordinate.child? || !EXCLUDE_FROM_BLOCK.include?(type_champ)
|
||||
end
|
||||
|
||||
def filter_public_or_private_only_type_champ(type_champ)
|
||||
if coordinate.private?
|
||||
true
|
||||
else
|
||||
!TypeDeChamp::PRIVATE_ONLY_TYPES.include?(type_champ)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_featured_type_champ(type_champ)
|
||||
feature_name = TypeDeChamp::FEATURE_FLAGS[type_champ.to_sym]
|
||||
feature_name.blank? || procedure.feature_enabled?(feature_name)
|
||||
|
|
|
@ -11,14 +11,22 @@ module Administrateurs
|
|||
if @configuration.valid?
|
||||
@procedure.update!(chorus: @configuration.attributes)
|
||||
|
||||
flash.notice = "La configuration Chorus a été mise à jour et prend immédiatement effet pour les nouveaux dossiers."
|
||||
redirect_to admin_procedure_path(@procedure)
|
||||
if @configuration.complete?
|
||||
flash.notice = "La configuration Chorus a été mise à jour."
|
||||
redirect_to add_champ_engagement_juridique_admin_procedure_chorus_path(@procedure)
|
||||
else
|
||||
flash.notice = "La configuration Chorus a été mise à jour. Veuillez renseigner le reste des informations pour faciliter le rapprochement des données."
|
||||
redirect_to edit_admin_procedure_chorus_path(@procedure)
|
||||
end
|
||||
else
|
||||
flash.now.alert = "Des erreurs empêchent la validation du connecteur chorus. Corrigez les erreurs"
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def add_champ_engagement_juridique
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def search_params
|
||||
|
@ -27,7 +35,7 @@ module Administrateurs
|
|||
|
||||
def configurations_params
|
||||
params.require(:chorus_configuration)
|
||||
.permit(:centre_de_coup, :domaine_fonctionnel, :referentiel_de_programmation)
|
||||
.permit(:centre_de_cout, :domaine_fonctionnel, :referentiel_de_programmation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ class DataSources::ChorusController < ApplicationController
|
|||
def search_centre_couts
|
||||
result_json = APIBretagneService.new.search_centre_couts(code_or_label: params[:q])
|
||||
render json: format_result(result_json:,
|
||||
label_formatter: ChorusConfiguration.method(:format_centre_de_coup_label))
|
||||
label_formatter: ChorusConfiguration.method(:format_centre_de_cout_label))
|
||||
end
|
||||
|
||||
def search_ref_programmation
|
||||
|
@ -25,7 +25,7 @@ class DataSources::ChorusController < ApplicationController
|
|||
result_json.map do |item|
|
||||
{
|
||||
label: label_formatter.call(item),
|
||||
value: "#{item[:label]} - #{item[:code_programme]}",
|
||||
value: item[:code],
|
||||
data: item
|
||||
}
|
||||
end
|
||||
|
|
|
@ -116,7 +116,8 @@ class API::V2::Schema < GraphQL::Schema
|
|||
Types::Champs::Descriptor::TextChampDescriptorType,
|
||||
Types::Champs::Descriptor::TitreIdentiteChampDescriptorType,
|
||||
Types::Champs::Descriptor::YesNoChampDescriptorType,
|
||||
Types::Champs::Descriptor::ExpressionReguliereChampDescriptorType
|
||||
Types::Champs::Descriptor::ExpressionReguliereChampDescriptorType,
|
||||
Types::Champs::Descriptor::EngagementJuridiqueChampDescriptorType
|
||||
|
||||
def self.unauthorized_object(error)
|
||||
# Add a top-level error to the response instead of returning nil:
|
||||
|
|
|
@ -2172,6 +2172,34 @@ type EmailChampDescriptor implements ChampDescriptor {
|
|||
type: TypeDeChamp! @deprecated(reason: "Utilisez le champ `__typename` à la place.")
|
||||
}
|
||||
|
||||
type EngagementJuridiqueChampDescriptor implements ChampDescriptor {
|
||||
"""
|
||||
Description des champs d’un bloc répétable.
|
||||
"""
|
||||
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
|
||||
|
||||
"""
|
||||
Description du champ.
|
||||
"""
|
||||
description: String
|
||||
id: ID!
|
||||
|
||||
"""
|
||||
Libellé du champ.
|
||||
"""
|
||||
label: String!
|
||||
|
||||
"""
|
||||
Est-ce que le champ est obligatoire ?
|
||||
"""
|
||||
required: Boolean!
|
||||
|
||||
"""
|
||||
Type de la valeur du champ.
|
||||
"""
|
||||
type: TypeDeChamp! @deprecated(reason: "Utilisez le champ `__typename` à la place.")
|
||||
}
|
||||
|
||||
type Entreprise {
|
||||
attestationFiscaleAttachment: File
|
||||
attestationSocialeAttachment: File
|
||||
|
@ -4019,6 +4047,11 @@ enum TypeDeChamp {
|
|||
"""
|
||||
email
|
||||
|
||||
"""
|
||||
Translation missing: fr.activerecord.attributes.type_de_champ.type_champs.engagement_juridique
|
||||
"""
|
||||
engagement_juridique
|
||||
|
||||
"""
|
||||
EPCI
|
||||
"""
|
||||
|
|
|
@ -22,6 +22,9 @@ module Types
|
|||
definition_methods do
|
||||
def resolve_type(object, context)
|
||||
case object.type_champ
|
||||
when TypeDeChamp.type_champs.fetch(:engagement_juridique)
|
||||
Types::Champs::Descriptor::EngagementJuridiqueChampDescriptorType
|
||||
|
||||
when TypeDeChamp.type_champs.fetch(:text)
|
||||
Types::Champs::Descriptor::TextChampDescriptorType
|
||||
when TypeDeChamp.type_champs.fetch(:textarea)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module Types::Champs::Descriptor
|
||||
class EngagementJuridiqueChampDescriptorType < Types::BaseObject
|
||||
implements Types::ChampDescriptorType
|
||||
end
|
||||
end
|
7
app/models/champs/engagement_juridique_champ.rb
Normal file
7
app/models/champs/engagement_juridique_champ.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class Champs::EngagementJuridiqueChamp < Champ
|
||||
# cf: https://communaute.chorus-pro.gouv.fr/documentation/creer-un-engagement/#1522314752186-a34f3662-0644b5d1-16c22add-8ea097de-3a0a
|
||||
validates_with ExpressionReguliereValidator,
|
||||
expression_reguliere: /([A-Z]|[0-9]|\-|\_|\+|\/)+/,
|
||||
expression_reguliere_error_message: "Le numéro d'EJ ne peut contenir que des caractères alphanumérique et les caractères spéciaux suivant : “-“ ; “_“ ; “+“ ; “/“",
|
||||
if: -> { validation_context != :brouillon }
|
||||
end
|
|
@ -2,37 +2,11 @@ class ChorusConfiguration
|
|||
include ActiveModel::Model
|
||||
include ActiveModel::Attributes
|
||||
|
||||
attribute :centre_de_coup, :simple_json, default: '{}'
|
||||
attribute :centre_de_cout, :simple_json, default: '{}'
|
||||
attribute :domaine_fonctionnel, :simple_json, default: '{}'
|
||||
attribute :referentiel_de_programmation, :simple_json, default: '{}'
|
||||
|
||||
def format_displayed_value(attribute_name)
|
||||
case attribute_name
|
||||
when :centre_de_coup
|
||||
ChorusConfiguration.format_centre_de_coup_label(centre_de_coup)
|
||||
when :domaine_fonctionnel
|
||||
ChorusConfiguration.format_domaine_fonctionnel_label(domaine_fonctionnel)
|
||||
when :referentiel_de_programmation
|
||||
ChorusConfiguration.format_ref_programmation_label(referentiel_de_programmation)
|
||||
else
|
||||
raise 'unknown attribute_name'
|
||||
end
|
||||
end
|
||||
|
||||
def format_hidden_value(attribute_name)
|
||||
case attribute_name
|
||||
when :centre_de_coup
|
||||
centre_de_coup.to_json
|
||||
when :domaine_fonctionnel
|
||||
domaine_fonctionnel.to_json
|
||||
when :referentiel_de_programmation
|
||||
referentiel_de_programmation.to_json
|
||||
else
|
||||
raise 'unknown attribute_name'
|
||||
end
|
||||
end
|
||||
|
||||
def self.format_centre_de_coup_label(api_result)
|
||||
def self.format_centre_de_cout_label(api_result)
|
||||
return "" if api_result.blank?
|
||||
api_result = api_result.symbolize_keys
|
||||
"#{api_result[:description]} - #{api_result[:code]}"
|
||||
|
@ -52,7 +26,7 @@ class ChorusConfiguration
|
|||
|
||||
def complete?
|
||||
[
|
||||
centre_de_coup,
|
||||
centre_de_cout,
|
||||
domaine_fonctionnel,
|
||||
referentiel_de_programmation
|
||||
].all?(&:present?)
|
||||
|
|
|
@ -7,7 +7,7 @@ module ProcedureChorusConcern
|
|||
end
|
||||
|
||||
def chorusable?
|
||||
feature_enabled?(:chorus)
|
||||
feature_enabled?(:engagement_juridique_type_de_champ)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1228,6 +1228,13 @@ class Dossier < ApplicationRecord
|
|||
columns << ['Entreprise raison sociale', etablissement&.entreprise_raison_sociale]
|
||||
end
|
||||
|
||||
if procedure.chorusable? && procedure.chorus.complete?
|
||||
columns += [
|
||||
['Domaine Fonctionnel', procedure.chorus_configuration.domaine_fonctionnel.code],
|
||||
['Référentiel De Programmation', procedure.chorus_configuration.referentiel_de_programmation.code],
|
||||
['Centre De Coup', procedure.chorus_configuration.centre_de_cout.code]
|
||||
]
|
||||
end
|
||||
columns += [
|
||||
['Archivé', :archived],
|
||||
['État du dossier', Dossier.human_attribute_name("state.#{state}")],
|
||||
|
|
|
@ -3,9 +3,12 @@ class TypeDeChamp < ApplicationRecord
|
|||
|
||||
FILE_MAX_SIZE = 200.megabytes
|
||||
FEATURE_FLAGS = {
|
||||
engagement_juridique: :engagement_juridique_type_de_champ,
|
||||
|
||||
cojo: :cojo_type_de_champ,
|
||||
expression_reguliere: :expression_reguliere_type_de_champ
|
||||
}
|
||||
|
||||
MINIMUM_TEXTAREA_CHARACTER_LIMIT_LENGTH = 400
|
||||
|
||||
STRUCTURE = :structure
|
||||
|
@ -20,6 +23,8 @@ class TypeDeChamp < ApplicationRecord
|
|||
CATEGORIES = [STRUCTURE, ETAT_CIVIL, LOCALISATION, PAIEMENT_IDENTIFICATION, STANDARD, PIECES_JOINTES, CHOICE, REFERENTIEL_EXTERNE]
|
||||
|
||||
TYPE_DE_CHAMP_TO_CATEGORIE = {
|
||||
engagement_juridique: REFERENTIEL_EXTERNE,
|
||||
|
||||
header_section: STRUCTURE,
|
||||
repetition: STRUCTURE,
|
||||
dossier_link: STRUCTURE,
|
||||
|
@ -62,6 +67,8 @@ class TypeDeChamp < ApplicationRecord
|
|||
}
|
||||
|
||||
enum type_champs: {
|
||||
engagement_juridique: 'engagement_juridique',
|
||||
|
||||
header_section: 'header_section',
|
||||
repetition: 'repetition',
|
||||
dossier_link: 'dossier_link',
|
||||
|
@ -111,6 +118,10 @@ class TypeDeChamp < ApplicationRecord
|
|||
type_champs.fetch(:epci)
|
||||
]
|
||||
|
||||
PRIVATE_ONLY_TYPES = [
|
||||
type_champs.fetch(:engagement_juridique)
|
||||
]
|
||||
|
||||
store_accessor :options,
|
||||
:cadastres,
|
||||
:old_pj,
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
class TypesDeChamp::EngagementJuridiqueTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||
end
|
|
@ -2,9 +2,12 @@ class ExpressionReguliereValidator < ActiveModel::Validator
|
|||
TIMEOUT = 1.second.freeze
|
||||
|
||||
def validate(record)
|
||||
expression_reguliere = options[:expression_reguliere] || record.expression_reguliere
|
||||
expression_reguliere_error_message = options[:expression_reguliere_error_message] || record.expression_reguliere_error_message
|
||||
|
||||
if record.value.present?
|
||||
if !record.value.match?(Regexp.new(record.expression_reguliere, timeout: TIMEOUT))
|
||||
record.errors.add(:value, :invalid_regexp, expression_reguliere_error_message: record.expression_reguliere_error_message)
|
||||
if !record.value.match?(Regexp.new(expression_reguliere, timeout: TIMEOUT))
|
||||
record.errors.add(:value, :invalid_regexp, expression_reguliere_error_message: expression_reguliere_error_message)
|
||||
end
|
||||
end
|
||||
rescue Regexp::TimeoutError
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
= render partial: 'administrateurs/breadcrumbs',
|
||||
locals: { steps: [['Démarches', admin_procedures_path],
|
||||
[@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)],
|
||||
['Connecteur Chorus']] }
|
||||
|
||||
|
||||
.fr-container
|
||||
%h1.fr-h1
|
||||
Cadre budgétaire
|
||||
|
||||
= render Dsfr::CalloutComponent.new(title: "Cas d'usage") do |c|
|
||||
- c.with_body do
|
||||
%p Ajouter un champs Engagement Juridique aux annotations privées afin de renseigner l'EJ directement dans DS
|
||||
%p L'EJ sera automatiquement ajouté aux exports des dossiers
|
||||
|
||||
= link_to "Ajouter une annotation privée EJ", annotations_admin_procedure_path(@procedure), class: 'btn fr-btn'
|
|
@ -8,4 +8,11 @@
|
|||
%h1.fr-h1
|
||||
Cadre budgétaire
|
||||
|
||||
= render Dsfr::CalloutComponent.new(title: "Cas d'usage") do |c|
|
||||
- c.with_body do
|
||||
%p Vous traitez une démarche liées a des subventions qui seront payées au travers de Chorus ?
|
||||
%p Les agent traitants les dossiers seront ammenés a suivre la planification budgetaire des dossiers traités ?
|
||||
%p En renseignant le cadre budgetaire de la subvention, vous donnez les moyens de rapprocher les dossiers traités sur démarches-simplifiées avec les données extraites de Chorus
|
||||
%p Ce cadre budgetaire sera automatiquement ajouté aux exports des dossiers
|
||||
|
||||
= render Procedure::ChorusFormComponent.new(procedure: @procedure)
|
||||
|
|
|
@ -619,7 +619,9 @@ Rails.application.routes.draw do
|
|||
resource :attestation_template, only: [:show, :edit, :update, :create] do
|
||||
get 'preview', on: :member
|
||||
end
|
||||
resource :chorus, only: [:edit, :update]
|
||||
resource :chorus, only: [:edit, :update] do
|
||||
get 'add_champ_engagement_juridique'
|
||||
end
|
||||
resource :dossier_submitted_message, only: [:edit, :update, :create]
|
||||
# ADDED TO ACCESS IT FROM THE IFRAME
|
||||
get 'attestation_template/preview' => 'attestation_templates#preview'
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_10_26_161609) do
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_11_03_084116) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pgcrypto"
|
||||
enable_extension "plpgsql"
|
||||
|
|
|
@ -13,7 +13,7 @@ describe Procedure::Card::ChorusComponent, type: :component do
|
|||
end
|
||||
end
|
||||
context 'feature flag active' do
|
||||
before { Flipper.enable_actor :chorus, procedure }
|
||||
before { Flipper.enable_actor :engagement_juridique_type_de_champ, procedure }
|
||||
|
||||
it 'render the template' do
|
||||
subject
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
describe TypesDeChampEditor::ChampComponent, type: :component do
|
||||
describe 'render' do
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :drop_down_list, libelle: 'Votre ville', options: ['Paris', 'Lyon', 'Marseille'] }]) }
|
||||
let(:drop_down_tdc) { procedure.draft_revision.types_de_champ.first }
|
||||
let(:coordinate) { drop_down_tdc.revision_type_de_champ }
|
||||
let(:component) { described_class.new(coordinate:, upper_coordinates: []) }
|
||||
let(:routing_rules_stable_ids) { [] }
|
||||
|
||||
before do
|
||||
Flipper.enable_actor(:engagement_juridique_type_de_champ, procedure)
|
||||
allow_any_instance_of(Procedure).to receive(:stable_ids_used_by_routing_rules).and_return(routing_rules_stable_ids)
|
||||
render_inline(component)
|
||||
end
|
||||
|
||||
describe 'tdc dropdown' do
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :drop_down_list, libelle: 'Votre ville', options: ['Paris', 'Lyon', 'Marseille'] }]) }
|
||||
let(:tdc) { procedure.draft_revision.types_de_champ.first }
|
||||
let(:coordinate) { tdc.revision_type_de_champ }
|
||||
|
||||
context 'drop down tdc not used for routing' do
|
||||
it do
|
||||
expect(page).not_to have_text(/utilisé pour\nle routage/)
|
||||
|
@ -19,7 +22,7 @@ describe TypesDeChampEditor::ChampComponent, type: :component do
|
|||
end
|
||||
|
||||
context 'drop down tdc used for routing' do
|
||||
let(:routing_rules_stable_ids) { [drop_down_tdc.stable_id] }
|
||||
let(:routing_rules_stable_ids) { [tdc.stable_id] }
|
||||
|
||||
it do
|
||||
expect(page).to have_css("select[disabled=\"disabled\"]")
|
||||
|
@ -27,4 +30,25 @@ describe TypesDeChampEditor::ChampComponent, type: :component do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'tdc ej' do
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :text }], types_de_champ_private: [{ type: :text }]) }
|
||||
|
||||
context 'when coordinate public' do
|
||||
let(:coordinate) { procedure.draft_revision.revision_types_de_champ_public.first }
|
||||
|
||||
it 'does not include Engagement Juridique' do
|
||||
expect(page).not_to have_css('option', text: "Engagement Juridique")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when coordinate private' do
|
||||
let(:coordinate) { procedure.draft_revision.revision_types_de_champ_private.first }
|
||||
|
||||
it 'includes Engagement Juridique' do
|
||||
expect(page).to have_css('option', text: "Engagement Juridique")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
describe Administrateurs::ChorusController, type: :controller do
|
||||
describe 'edit' do
|
||||
let(:user) { create(:user) }
|
||||
let(:admin) { create(:administrateur, user: create(:user)) }
|
||||
let(:procedure) { create(:procedure, administrateurs: [admin]) }
|
||||
|
||||
describe '#edit' do
|
||||
subject { get :edit, params: { procedure_id: procedure.id } }
|
||||
|
||||
context 'not signed in' do
|
||||
context 'when user is not signed in' do
|
||||
it { is_expected.to redirect_to(new_user_session_path) }
|
||||
end
|
||||
|
||||
context 'signed in but not admin of procedure' do
|
||||
context 'when user is signed in but not admin of procedure' do
|
||||
before { sign_in(user) }
|
||||
it { is_expected.to redirect_to(new_user_session_path) }
|
||||
end
|
||||
|
||||
context 'signed as admin' do
|
||||
context 'when user is signed as admin' do
|
||||
before { sign_in(admin.user) }
|
||||
it { is_expected.to have_http_status(200) }
|
||||
|
||||
|
@ -26,10 +27,7 @@ describe Administrateurs::ChorusController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'update' do
|
||||
let(:user) { create(:user) }
|
||||
let(:admin) { create(:administrateur, user: create(:user)) }
|
||||
let(:procedure) { create(:procedure, administrateurs: [admin]) }
|
||||
describe '#update' do
|
||||
let(:chorus_configuration_params) { {} }
|
||||
subject do
|
||||
put :update,
|
||||
|
@ -39,38 +37,83 @@ describe Administrateurs::ChorusController, type: :controller do
|
|||
}
|
||||
end
|
||||
|
||||
context 'not signed in' do
|
||||
context 'when user is not signed in' do
|
||||
it { is_expected.to redirect_to(new_user_session_path) }
|
||||
end
|
||||
|
||||
context 'signed in but not admin of procedure' do
|
||||
context 'when user is signed in but not admin of procedure' do
|
||||
before { sign_in(user) }
|
||||
it { is_expected.to redirect_to(new_user_session_path) }
|
||||
end
|
||||
|
||||
context 'signed as admin' do
|
||||
context 'when user is signed as admin' do
|
||||
before { sign_in(admin.user) }
|
||||
let(:domaine_fonctionnel) { nil }
|
||||
let(:referentiel_de_programmation) { nil }
|
||||
|
||||
context "valid payload" do
|
||||
let(:centre_de_coup) { '{"code":"D00C8DX004","label":"Aumôniers+protestant","ville":null,"code_postal":null,"description":"Aumoniers+protestants"}' }
|
||||
context "partial valid payload" do
|
||||
let(:centre_de_cout) { '{"code":"D00C8DX004","label":"Aumôniers+protestant","ville":null,"code_postal":null,"description":"Aumoniers+protestants"}' }
|
||||
let(:chorus_configuration_params) do
|
||||
{
|
||||
centre_de_cout:, domaine_fonctionnel:, referentiel_de_programmation:
|
||||
}
|
||||
end
|
||||
it 'updates params and redirect back to complete all infos' do
|
||||
expect(subject).to redirect_to(edit_admin_procedure_chorus_path(procedure))
|
||||
expect(flash[:notice]).to eq("La configuration Chorus a été mise à jour. Veuillez renseigner le reste des informations pour faciliter le rapprochement des données.")
|
||||
|
||||
procedure.reload
|
||||
|
||||
expect(procedure.chorus_configuration.centre_de_cout).to eq(JSON.parse(centre_de_cout))
|
||||
expect(procedure.chorus_configuration.domaine_fonctionnel).to eq(nil)
|
||||
expect(procedure.chorus_configuration.referentiel_de_programmation).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "full valid payload" do
|
||||
let(:centre_de_cout) { '{"code":"D00C8DX004","label":"Aumôniers+protestant","ville":null,"code_postal":null,"description":"Aumoniers+protestants"}' }
|
||||
let(:domaine_fonctionnel) { '{"code":"0105-05-01","label":"Formation+des+élites+et+cadres+de+sécurité+et+de+défense","description":null,"code_programme":"105"}' }
|
||||
let(:referentiel_de_programmation) { '{"code":"010101010101","label":"DOTATIONS+CARPA+AJ+ET+AUTRES+INTERVENTIONS","description":null,"code_programme":"101"}' }
|
||||
let(:chorus_configuration_params) do
|
||||
{
|
||||
centre_de_coup:, domaine_fonctionnel:, referentiel_de_programmation:
|
||||
centre_de_cout:, domaine_fonctionnel:, referentiel_de_programmation:
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to redirect_to(admin_procedure_path(procedure)) }
|
||||
it 'updates params' do
|
||||
subject
|
||||
expect(flash[:notice]).to eq("La configuration Chorus a été mise à jour et prend immédiatement effet pour les nouveaux dossiers.")
|
||||
it 'updates params and redirects to add champs EngagementJuridique' do
|
||||
expect(subject).to redirect_to(add_champ_engagement_juridique_admin_procedure_chorus_path(procedure))
|
||||
expect(flash[:notice]).to eq("La configuration Chorus a été mise à jour.")
|
||||
|
||||
procedure.reload
|
||||
expect(procedure.chorus_configuration.centre_de_coup).to eq(JSON.parse(centre_de_coup))
|
||||
|
||||
expect(procedure.chorus_configuration.centre_de_cout).to eq(JSON.parse(centre_de_cout))
|
||||
expect(procedure.chorus_configuration.domaine_fonctionnel).to eq(JSON.parse(domaine_fonctionnel))
|
||||
expect(procedure.chorus_configuration.referentiel_de_programmation).to eq(JSON.parse(referentiel_de_programmation))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#add_champ_engagement_juridique' do
|
||||
render_views
|
||||
subject { get :add_champ_engagement_juridique, params: { procedure_id: procedure.id } }
|
||||
|
||||
context 'when user is not signed in' do
|
||||
it { is_expected.to redirect_to(new_user_session_path) }
|
||||
end
|
||||
|
||||
context 'when user is signed in but not admin of procedure' do
|
||||
before { sign_in(user) }
|
||||
it { is_expected.to redirect_to(new_user_session_path) }
|
||||
end
|
||||
|
||||
context 'when user is signed as admin' do
|
||||
before { sign_in(admin.user) }
|
||||
|
||||
it 'have links to add annotation' do
|
||||
expect(subject).to have_http_status(:success)
|
||||
expect(response.body).to have_link("Ajouter une annotation privée EJ", href: annotations_admin_procedure_path(procedure))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -238,6 +238,9 @@ FactoryBot.define do
|
|||
value { 'W173847273' }
|
||||
end
|
||||
|
||||
factory :champ_engagement_juridique, class: 'Champs::EngagementJuridiqueChamp' do
|
||||
type_de_champ { association :type_de_champ_engagement_juridique, procedure: dossier.procedure }
|
||||
end
|
||||
factory :champ_cojo, class: 'Champs::COJOChamp' do
|
||||
type_de_champ { association :type_de_champ_cojo, procedure: dossier.procedure }
|
||||
end
|
||||
|
|
|
@ -428,12 +428,12 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
trait :partial_chorus do
|
||||
chorus { ChorusConfiguration.new(centre_de_coup: { a: 1 }) }
|
||||
chorus { ChorusConfiguration.new(centre_de_cout: { a: 1 }) }
|
||||
end
|
||||
|
||||
trait :filled_chorus do
|
||||
chorus do
|
||||
ChorusConfiguration.new(centre_de_coup: { a: 1 },
|
||||
ChorusConfiguration.new(centre_de_cout: { a: 1 },
|
||||
domaine_fonctionnel: { b: 2 },
|
||||
referentiel_de_programmation: { c: 3 })
|
||||
end
|
||||
|
|
|
@ -184,6 +184,9 @@ FactoryBot.define do
|
|||
factory :type_de_champ_epci do
|
||||
type_champ { TypeDeChamp.type_champs.fetch(:epci) }
|
||||
end
|
||||
factory :type_de_champ_engagement_juridique do
|
||||
type_champ { TypeDeChamp.type_champs.fetch(:engagement_juridique) }
|
||||
end
|
||||
factory :type_de_champ_cojo do
|
||||
type_champ { TypeDeChamp.type_champs.fetch(:cojo) }
|
||||
end
|
||||
|
|
|
@ -14,9 +14,9 @@ describe '20220705164551_remove_unused_champs' do
|
|||
|
||||
describe 'remove_unused_champs' do
|
||||
it "with bad champs" do
|
||||
expect(Champ.where(dossier: dossier).count).to eq(43)
|
||||
expect(Champ.where(dossier: dossier).count).to eq(44)
|
||||
run_task
|
||||
expect(Champ.where(dossier: dossier).count).to eq(42)
|
||||
expect(Champ.where(dossier: dossier).count).to eq(43)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ describe ChorusConfiguration do
|
|||
it 'works with existing args' do
|
||||
expect do
|
||||
cc = ChorusConfiguration.new()
|
||||
cc.assign_attributes(centre_de_coup: {}, domaine_fonctionnel: {}, referentiel_de_programmation: {})
|
||||
cc.assign_attributes(centre_de_cout: {}, domaine_fonctionnel: {}, referentiel_de_programmation: {})
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
|
41
spec/models/engagement_juridique_champ_spec.rb
Normal file
41
spec/models/engagement_juridique_champ_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
describe Champs::EngagementJuridiqueChamp do
|
||||
describe 'validation' do
|
||||
let(:champ) { build(:champ_engagement_juridique, value: value) }
|
||||
subject { champ.valid? }
|
||||
|
||||
context 'with [A-Z]' do
|
||||
let(:value) { "ABC" }
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'with [0-9]' do
|
||||
let(:value) { "ABC" }
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'with -' do
|
||||
let(:value) { "-" }
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'with _' do
|
||||
let(:value) { "_" }
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'with +' do
|
||||
let(:value) { "+" }
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'with /' do
|
||||
let(:value) { "/" }
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'with *' do
|
||||
let(:value) { "*" }
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -91,7 +91,8 @@ describe ProcedureExportService do
|
|||
"epci (Département)",
|
||||
"cojo",
|
||||
"expression_reguliere",
|
||||
"rnf"
|
||||
"rnf",
|
||||
"engagement_juridique"
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -140,6 +141,21 @@ describe ProcedureExportService do
|
|||
end
|
||||
it { expect(dossiers_sheet.data.first.size).to eq(nominal_headers.size) }
|
||||
end
|
||||
|
||||
context 'with procedure chorus' do
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, :filled_chorus, :with_all_champs) }
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, procedure: procedure) }
|
||||
|
||||
it 'includes chorus headers' do
|
||||
expected_headers = [
|
||||
'Domaine Fonctionnel',
|
||||
'Référentiel De Programmation',
|
||||
'Centre De Coup'
|
||||
]
|
||||
|
||||
expect(dossiers_sheet.headers).to match_array(nominal_headers)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Etablissement sheet' do
|
||||
|
@ -204,7 +220,8 @@ describe ProcedureExportService do
|
|||
"epci (Département)",
|
||||
"cojo",
|
||||
"expression_reguliere",
|
||||
"rnf"
|
||||
"rnf",
|
||||
"engagement_juridique"
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -300,7 +317,8 @@ describe ProcedureExportService do
|
|||
"epci (Département)",
|
||||
"cojo",
|
||||
"expression_reguliere",
|
||||
"rnf"
|
||||
"rnf",
|
||||
"engagement_juridique"
|
||||
]
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue