diff --git a/Gemfile b/Gemfile index 2cc337335..25829f8ee 100644 --- a/Gemfile +++ b/Gemfile @@ -59,6 +59,7 @@ gem 'lograge' gem 'logstash-event' gem 'mailjet', require: false gem 'matrix' # needed by prawn and not default in ruby 3.1 +gem 'mini_magick' gem 'net-imap', require: false # See https://github.com/mikel/mail/pull/1439 gem 'net-pop', require: false # same gem 'net-smtp', require: false # same @@ -105,6 +106,7 @@ group :test do gem 'rack_session_access' gem 'rails-controller-testing' gem 'rspec_junit_formatter' + gem 'rspec-retry' gem 'selenium-devtools' gem 'selenium-webdriver' gem 'shoulda-matchers', require: false @@ -114,7 +116,6 @@ group :test do end group :development do - gem 'annotate' gem 'brakeman', require: false gem 'haml-lint' gem 'letter_opener_web' diff --git a/Gemfile.lock b/Gemfile.lock index d6e81d6e9..dda1c8814 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -101,9 +101,6 @@ GEM aes_key_wrap (1.1.0) after_party (1.11.2) anchored (1.1.0) - annotate (3.2.0) - activerecord (>= 3.2, < 8.0) - rake (>= 10.4, < 14.0) ast (2.4.2) attr_required (1.0.1) axe-core-api (4.2.1) @@ -490,7 +487,7 @@ GEM pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (5.0.1) - puma (6.1.1) + puma (6.3.1) nio4r (~> 2.0) pundit (2.2.0) activesupport (>= 3.0.0) @@ -604,6 +601,8 @@ GEM rspec-expectations (~> 3.11) rspec-mocks (~> 3.11) rspec-support (~> 3.11) + rspec-retry (0.6.2) + rspec-core (> 3.3) rspec-support (3.12.0) rspec_junit_formatter (0.4.1) rspec-core (>= 2, < 4, != 2.12.0) @@ -813,7 +812,6 @@ DEPENDENCIES administrate-field-enum after_party anchored - annotate axe-core-rspec bcrypt bootsnap (>= 1.4.4) @@ -872,6 +870,7 @@ DEPENDENCIES matrix memory_profiler mina + mini_magick net-imap net-pop net-smtp @@ -898,6 +897,7 @@ DEPENDENCIES rexml rqrcode rspec-rails + rspec-retry rspec_junit_formatter rubocop rubocop-performance diff --git a/app/assets/stylesheets/02_utils.scss b/app/assets/stylesheets/02_utils.scss index d4d6f21ce..277a56688 100644 --- a/app/assets/stylesheets/02_utils.scss +++ b/app/assets/stylesheets/02_utils.scss @@ -102,6 +102,10 @@ white-space: nowrap; } +.width-max-content { + width: max-content; +} + // sizing .width-100 { width: 100%; diff --git a/app/assets/stylesheets/dsfr.scss b/app/assets/stylesheets/dsfr.scss index a2f734412..7eb7a5569 100644 --- a/app/assets/stylesheets/dsfr.scss +++ b/app/assets/stylesheets/dsfr.scss @@ -2,7 +2,7 @@ // overwrite DSFR style for SimpleFormatComponent, some user use markdown with // ordered list having paragraph between list item -.fr-ol-content--override { +ol.fr-ol-content--override { list-style-type: decimal; li::marker { diff --git a/app/assets/stylesheets/invites_form.scss b/app/assets/stylesheets/invites_form.scss index cfd4ea2e1..b0fc6c938 100644 --- a/app/assets/stylesheets/invites_form.scss +++ b/app/assets/stylesheets/invites_form.scss @@ -1,34 +1,6 @@ -@import "constants"; #invites-form { - padding: $default-padding; - text-align: left; - - form { - display: flex; - margin-top: $default-padding; - } - - h4 { - font-weight: bold; - margin-bottom: $default-spacer; - } - - p { - margin-bottom: $default-spacer; - } - - ul { - list-style-position: inside; - list-style-type: disc; - margin-bottom: $default-padding; - } - - input[type=email] { - margin-bottom: $default-spacer; - } - - .button { - margin-left: $default-spacer; + @media (min-width: 48em) { + min-width: 400px; } } diff --git a/app/components/dsfr/input_errorable.rb b/app/components/dsfr/input_errorable.rb index 9c8164172..294c2cd27 100644 --- a/app/components/dsfr/input_errorable.rb +++ b/app/components/dsfr/input_errorable.rb @@ -1,10 +1,13 @@ module Dsfr module InputErrorable extend ActiveSupport::Concern + included do delegate :object, to: :@form delegate :errors, to: :object + renders_one :hint + private # lookup for edge case from `form.rich_text_area` @@ -89,6 +92,10 @@ module Dsfr end def hint + get_slot(:hint).presence || default_hint + end + + def default_hint I18n.t("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}") end @@ -101,6 +108,8 @@ module Dsfr end def hint? + return true if get_slot(:hint).present? + I18n.exists?("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}") end end diff --git a/app/components/instructeurs/activate_account_form_component.rb b/app/components/instructeurs/activate_account_form_component.rb new file mode 100644 index 000000000..3cd66c102 --- /dev/null +++ b/app/components/instructeurs/activate_account_form_component.rb @@ -0,0 +1,6 @@ +class Instructeurs::ActivateAccountFormComponent < ApplicationComponent + attr_reader :user + def initialize(user:) + @user = user + end +end diff --git a/app/components/instructeurs/activate_account_form_component/activate_account_form_component.en.yml b/app/components/instructeurs/activate_account_form_component/activate_account_form_component.en.yml new file mode 100644 index 000000000..187694837 --- /dev/null +++ b/app/components/instructeurs/activate_account_form_component/activate_account_form_component.en.yml @@ -0,0 +1,6 @@ +--- +en: + title: Create your account for %{application_name} + activate: Activate your account %{email} + email_disabled: Instructor email address not changeable + submit: Choose password diff --git a/app/components/instructeurs/activate_account_form_component/activate_account_form_component.fr.yml b/app/components/instructeurs/activate_account_form_component/activate_account_form_component.fr.yml new file mode 100644 index 000000000..b797c16c1 --- /dev/null +++ b/app/components/instructeurs/activate_account_form_component/activate_account_form_component.fr.yml @@ -0,0 +1,7 @@ +--- +fr: + title: Création de compte sur %{application_name} + activate: Se créer un compte pour %{email} en choissant un mot de passe + email_disabled: Adresse instructeur non modifiable + submit: Définir le mot de passe + diff --git a/app/components/instructeurs/activate_account_form_component/activate_account_form_component.html.haml b/app/components/instructeurs/activate_account_form_component/activate_account_form_component.html.haml new file mode 100644 index 000000000..87d4dab3e --- /dev/null +++ b/app/components/instructeurs/activate_account_form_component/activate_account_form_component.html.haml @@ -0,0 +1,23 @@ += form_for user, url: { controller: 'users/activate', action: :create }, html: { class: "fr-py-5w" } do |f| + + %h1.fr-h2.fr-mb-7w= t('.title', application_name: APPLICATION_NAME) + + .fr-background-alt--grey.fr-px-12w.fr-py-7w + %fieldset.fr-mb-0.fr-fieldset{ aria: { labelledby: 'activate-account-legend' } } + + %legend.fr-fieldset__legend#activate-account-legend + %h2.fr-h6.fr-mb-0= t('.activate', email: user.email) + + .fr-fieldset__element + %p.fr-text--sm= t('utils.mandatory_champs') + + .fr-fieldset__element= render Dsfr::InputComponent.new(form: f, attribute: :email, input_type: :email_field, opts: { disabled: :disabled, class: 'fr-input-group--disabled', value: t('.email_disabled') }) + + .fr-fieldset__element= render Dsfr::InputComponent.new(form: f, attribute: :password, input_type: :password_field, opts: { autocomplete: 'current-password' }) + + = f.hidden_field :reset_password_token, value: params[:token] + + .fr-fieldset__element + .fr-btns-group--right.fr-btns-group.fr-btns-group--inline.fr-btns-group.fr-btns-group--inline + %ul + %li= f.submit t('.submit'), class: 'fr-mt-2v fr-btn fr-btn' diff --git a/app/components/procedure/instructeurs_options_component/instructeurs_options_component.fr.yml b/app/components/procedure/instructeurs_options_component/instructeurs_options_component.fr.yml index 50ceef368..1d98b2d9d 100644 --- a/app/components/procedure/instructeurs_options_component/instructeurs_options_component.fr.yml +++ b/app/components/procedure/instructeurs_options_component/instructeurs_options_component.fr.yml @@ -4,7 +4,7 @@ fr: Le routage permet d’acheminer les dossiers vers différents groupes d’instructeurs. routing_configuration_notice_2_html: |

Pour le configurer, votre formulaire doit comporter - au moins un champ « choix simple ».

+ au moins un champ de type « choix simple » ou « départements ».

Ajoutez ce champ dans la page « Configuration des champs ».

delete_title: Aucun dossier ne sera supprimé. Les groupes d'instructeurs vont être supprimés. Seuls les instructeurs du groupe « %{defaut_label} » resteront affectés à la démarche. delete_confirmation: | diff --git a/app/components/procedure/instructeurs_options_component/instructeurs_options_component.html.haml b/app/components/procedure/instructeurs_options_component/instructeurs_options_component.html.haml index 0835f6a1e..1fbfd047d 100644 --- a/app/components/procedure/instructeurs_options_component/instructeurs_options_component.html.haml +++ b/app/components/procedure/instructeurs_options_component/instructeurs_options_component.html.haml @@ -27,7 +27,7 @@ class: 'fr-btn', method: :delete, title: t('.delete_title', defaut_label: @procedure.defaut_groupe_instructeur.label), - data: ( @procedure.publiee? ? { disable_with: "Suppression...", confirm: t('.delete_confirmation', defaut_label: @procedure.defaut_groupe_instructeur.label) } : nil) + data: ( @procedure.publiee? ? { disable_with: "Suppression…", confirm: t('.delete_confirmation', defaut_label: @procedure.defaut_groupe_instructeur.label) } : nil) - elsif @state == 'choix' = form_for :choice, diff --git a/app/components/procedure/one_groupe_management_component.rb b/app/components/procedure/one_groupe_management_component.rb index bba162b9b..f1b8aa0e1 100644 --- a/app/components/procedure/one_groupe_management_component.rb +++ b/app/components/procedure/one_groupe_management_component.rb @@ -58,8 +58,18 @@ class Procedure::OneGroupeManagementComponent < ApplicationComponent def available_values_for_select(targeted_champ) return [] if targeted_champ.is_a?(Logic::Empty) - targeted_champ - .options(@revision.types_de_champ_public) - .map { |tdc| [tdc.first, constant(tdc.first).to_json] } + + case @revision.types_de_champ_public.find_by(stable_id: targeted_champ.stable_id).type_champ + when TypeDeChamp.type_champs.fetch(:departements) + departements_for_select + when TypeDeChamp.type_champs.fetch(:drop_down_list) + targeted_champ + .options(@revision.types_de_champ_public) + .map { |(label, value)| [label, constant(value).to_json] } + end + end + + def departements_for_select + APIGeoService.departements.map { ["#{_1[:code]} – #{_1[:name]}", constant(_1[:code]).to_json] } end end diff --git a/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml b/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml index cd7dcb4e0..518dc49a0 100644 --- a/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml +++ b/app/components/procedure/revision_changes_component/revision_changes_component.fr.yml @@ -9,6 +9,7 @@ fr: other: "%{count} dossiers en cours de traitement portent ce champ. Les données associées avec ce champ seront supprimées." add_option: "ajoutés : %{items}" remove_option: "supprimés : %{items}" + invalid_routing_rules_alert: "Certains groupes d'instructeurs ont une règle de routage invalide. Veuillez mettre à jour la configuration des groupes d'instructeurs après avoir publié les modifications." public: add: Le champ « %{label} » a été ajouté. add_mandatory: Le champ obligatoire « %{label} » a été ajouté. diff --git a/app/components/procedure/revision_changes_component/revision_changes_component.html.haml b/app/components/procedure/revision_changes_component/revision_changes_component.html.haml index 8325a5c41..8e71cab08 100644 --- a/app/components/procedure/revision_changes_component/revision_changes_component.html.haml +++ b/app/components/procedure/revision_changes_component/revision_changes_component.html.haml @@ -74,7 +74,7 @@ - if !total_dossiers.zero? && !change.can_rebase? .fr-alert.fr-alert--warning.fr-mt-1v %p= t('.breaking_change', count: total_dossiers) - - if removed.present? && change.type_de_champ.used_by_routing_rules? + - if (removed.present? || added.present? ) && change.type_de_champ.used_by_routing_rules? .fr-alert.fr-alert--warning.fr-mt-1v = t(".#{prefix}.update_drop_down_options_alert", label: change.label) - when :drop_down_other @@ -148,3 +148,7 @@ - if @private_move_changes.present? - list.with_item do = t(".private.move", count: @private_move_changes.size) + - if @previous_revision.procedure.routing_enabled? && @previous_revision.procedure.groupe_instructeurs.any?(&:invalid_rule?) + - list.with_item do + .fr-alert.fr-alert--warning.fr-mt-1v + = t(".invalid_routing_rules_alert") diff --git a/app/components/procedure/search_component/search_component.html.haml b/app/components/procedure/search_component/search_component.html.haml index 323a7665f..3ef7acbbe 100644 --- a/app/components/procedure/search_component/search_component.html.haml +++ b/app/components/procedure/search_component/search_component.html.haml @@ -1,11 +1,10 @@ -= form_tag(search_admin_procedures_path, data: { turbo: true }, method: :post, class: 'form') do - = label_tag :query, 'Rechercher une procédure' += form_tag(search_admin_procedures_path, data: { turbo: true }, method: :post) do + .fr-input-group + = label_tag :query, class: "fr-label" do + Rechercher une démarche + %span.fr-hint-text Saisissez au moins 3 lettres - .notice - %p Entrez au minimum 3 lettres - - - = text_field_tag :query, params[:query], required: true, placeholder: 'politique de la ville', minlength: "3" + = text_field_tag :query, params[:query], required: true, placeholder: 'politique de la ville', minlength: "3", class: "fr-input" = submit_tag 'Rechercher', class: 'fr-btn' diff --git a/app/controllers/administrateurs/groupe_instructeurs_controller.rb b/app/controllers/administrateurs/groupe_instructeurs_controller.rb index 101d05c1f..d042f74c4 100644 --- a/app/controllers/administrateurs/groupe_instructeurs_controller.rb +++ b/app/controllers/administrateurs/groupe_instructeurs_controller.rb @@ -40,12 +40,34 @@ module Administrateurs tdc = @procedure.active_revision.routable_types_de_champ.find { |tdc| tdc.stable_id == stable_id } - tdc_options = tdc.options["drop_down_options"].reject(&:empty?) + case tdc.type_champ + when TypeDeChamp.type_champs.fetch(:departements) + tdc_options = APIGeoService.departements.map { ["#{_1[:code]} – #{_1[:name]}", _1[:code]] } + tdc_options.each do |code_and_name, code| + routing_rule = ds_eq(champ_value(stable_id), constant(code)) + @procedure + .groupe_instructeurs + .find_or_create_by(label: code_and_name) + .update(instructeurs: [current_administrateur.instructeur], routing_rule:) + end - tdc_options.each do |option_label| - gi = @procedure.groupe_instructeurs.find_by({ label: option_label }) || @procedure.groupe_instructeurs - .create({ label: option_label, instructeurs: [current_administrateur.instructeur] }) - gi.update(routing_rule: ds_eq(champ_value(stable_id), constant(gi.label))) + when TypeDeChamp.type_champs.fetch(:drop_down_list) + tdc_options = tdc.drop_down_options.reject(&:empty?) + tdc_options.each do |option_label| + routing_rule = ds_eq(champ_value(stable_id), constant(option_label)) + @procedure + .groupe_instructeurs + .find_or_create_by(label: option_label) + .update(instructeurs: [current_administrateur.instructeur], routing_rule:) + end + end + + if tdc.drop_down_other? + routing_rule = ds_eq(champ_value(stable_id), constant(Champs::DropDownListChamp::OTHER)) + @procedure + .groupe_instructeurs + .find_or_create_by(label: 'Autre') + .update(instructeurs: [current_administrateur.instructeur], routing_rule:) end @procedure.toggle_routing diff --git a/app/controllers/api/public/v1/dossiers_controller.rb b/app/controllers/api/public/v1/dossiers_controller.rb index 718036d6e..3503a2def 100644 --- a/app/controllers/api/public/v1/dossiers_controller.rb +++ b/app/controllers/api/public/v1/dossiers_controller.rb @@ -4,7 +4,6 @@ class API::Public::V1::DossiersController < API::Public::V1::BaseController def create dossier = Dossier.new( revision: @procedure.active_revision, - groupe_instructeur: @procedure.defaut_groupe_instructeur_for_new_dossier, state: Dossier.states.fetch(:brouillon), prefilled: true ) diff --git a/app/controllers/api/v2/base_controller.rb b/app/controllers/api/v2/base_controller.rb index e3e166e9a..1deaa29cb 100644 --- a/app/controllers/api/v2/base_controller.rb +++ b/app/controllers/api/v2/base_controller.rb @@ -39,7 +39,9 @@ class API::V2::BaseController < ApplicationController def api_token if @api_token.nil? - @api_token = APIToken.find_and_verify(authorization_bearer_token) || false + @api_token = APIToken + .find_and_verify(authorization_bearer_token) + &.tap { _1.touch(:last_v2_authenticated_at) } || false end @api_token end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 55f4600b1..3a3adf757 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -6,6 +6,7 @@ class APIController < ApplicationController def find_administrateur_for_token(procedure) api_token = APIToken.find_and_verify(authorization_bearer_token, procedure.administrateurs) if api_token.present? && api_token.context.fetch(:procedure_ids).include?(procedure.id) + api_token.touch(:last_v1_authenticated_at) api_token.administrateur end end diff --git a/app/controllers/champs/options_controller.rb b/app/controllers/champs/options_controller.rb index 4f55ce070..9629865a3 100644 --- a/app/controllers/champs/options_controller.rb +++ b/app/controllers/champs/options_controller.rb @@ -1,8 +1,12 @@ class Champs::OptionsController < ApplicationController + include TurboChampsConcern + before_action :authenticate_logged_user! def remove - @champ = policy_scope(Champ).includes(:champs).find(params[:champ_id]) - @champ.remove_option([params[:option]].compact) + champ = policy_scope(Champ).includes(:champs).find(params[:champ_id]) + champ.remove_option([params[:option]].compact) + champs = champ.private? ? champ.dossier.champs_private_all : champ.dossier.champs_public_all + @to_show, @to_hide, @to_update = champs_to_turbo_update({ params[:champ_id] => true }, champs) end end diff --git a/app/controllers/instructeurs/dossiers_controller.rb b/app/controllers/instructeurs/dossiers_controller.rb index 848292abc..fe19bb1e9 100644 --- a/app/controllers/instructeurs/dossiers_controller.rb +++ b/app/controllers/instructeurs/dossiers_controller.rb @@ -85,7 +85,8 @@ module Instructeurs end def personnes_impliquees - @following_instructeurs_emails = dossier.followers_instructeurs.map(&:email) + # sort following_instructeurs (last follower on top) for the API of Agence de l'Eau Loire-Bretagne + @following_instructeurs_emails = dossier.followers_instructeurs.joins(:follows).merge(Follow.order(id: :desc)).map(&:email) previous_followers = dossier.previous_followers_instructeurs - dossier.followers_instructeurs @previous_following_instructeurs_emails = previous_followers.map(&:email) @avis_emails = dossier.experts.map(&:email) diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb index 5642d1fda..02640933e 100644 --- a/app/controllers/instructeurs/procedures_controller.rb +++ b/app/controllers/instructeurs/procedures_controller.rb @@ -224,19 +224,18 @@ module Instructeurs def email_usagers @procedure = procedure - @commentaire = Commentaire.new - @email_usagers_dossiers = email_usagers_dossiers - @dossiers_count = @email_usagers_dossiers.count - @groupe_instructeurs = email_usagers_groupe_instructeurs_label - @bulk_messages = BulkMessage.includes(:groupe_instructeurs).where(groupe_instructeurs: { id: current_instructeur.groupe_instructeur_ids, procedure: procedure }) + @bulk_messages = BulkMessage.includes(:groupe_instructeurs).where(groupe_instructeurs: { procedure: procedure }) + @bulk_message = current_instructeur.bulk_messages.build + @dossiers_without_groupe_count = procedure.dossiers.state_brouillon.for_groupe_instructeur(nil).count end def create_multiple_commentaire @procedure = procedure errors = [] - - email_usagers_dossiers.each do |dossier| - commentaire = CommentaireService.create(current_instructeur, dossier, commentaire_params) + bulk_message = current_instructeur.bulk_messages.build(bulk_message_params) + dossiers = procedure.dossiers.state_brouillon.for_groupe_instructeur(nil) + dossiers.each do |dossier| + commentaire = CommentaireService.create(current_instructeur, dossier, bulk_message_params.except(:targets)) if commentaire.errors.empty? commentaire.dossier.update!(last_commentaire_updated_at: Time.zone.now) else @@ -244,8 +243,15 @@ module Instructeurs end end - valid_dossiers_count = email_usagers_dossiers.count - errors.count - create_bulk_message_mail(valid_dossiers_count, Dossier.states.fetch(:brouillon)) + valid_dossiers_count = dossiers.count - errors.count + bulk_message.assign_attributes( + dossier_count: valid_dossiers_count, + dossier_state: Dossier.states.fetch(:brouillon), + sent_at: Time.zone.now, + instructeur_id: current_instructeur.id, + groupe_instructeurs: GroupeInstructeur.for_dossiers(dossiers) + ) + bulk_message.save! if errors.empty? flash[:notice] = "Tous les messages ont été envoyés avec succès" @@ -262,18 +268,6 @@ module Instructeurs private - def create_bulk_message_mail(dossier_count, dossier_state) - BulkMessage.create( - dossier_count: dossier_count, - dossier_state: dossier_state, - body: commentaire_params[:body], - sent_at: Time.zone.now, - instructeur_id: current_instructeur.id, - piece_jointe: commentaire_params[:piece_jointe], - groupe_instructeurs: email_usagers_groupe_instructeurs - ) - end - def assign_to_params params.require(:assign_to) .permit(:instant_expert_avis_email_notifications_enabled, :instant_email_dossier_notifications_enabled, :instant_email_message_notifications_enabled, :daily_email_notifications_enabled, :weekly_email_notifications_enabled) @@ -355,20 +349,8 @@ module Instructeurs @current_filters ||= procedure_presentation.filters.fetch(statut, []) end - def email_usagers_dossiers - procedure.dossiers.state_brouillon.where(groupe_instructeur: current_instructeur.groupe_instructeur_ids).includes(:groupe_instructeur) - end - - def email_usagers_groupe_instructeurs_label - email_usagers_dossiers.map(&:groupe_instructeur).uniq.map(&:label) - end - - def email_usagers_groupe_instructeurs - email_usagers_dossiers.map(&:groupe_instructeur).uniq - end - - def commentaire_params - params.require(:commentaire).permit(:body, :piece_jointe) + def bulk_message_params + params.require(:bulk_message).permit(:body) end end end diff --git a/app/controllers/manager/demandes_controller.rb b/app/controllers/manager/demandes_controller.rb deleted file mode 100644 index 06ae18389..000000000 --- a/app/controllers/manager/demandes_controller.rb +++ /dev/null @@ -1,62 +0,0 @@ -module Manager - class DemandesController < Manager::ApplicationController - def index - @pending_demandes = pending_demandes - end - - def create_administrateur - administrateur = current_super_admin.invite_admin(create_administrateur_params[:email]) - - if administrateur.errors.empty? - PipedriveAcceptsDealsJob.perform_later( - create_administrateur_params[:person_id], - current_super_admin.id, - create_administrateur_params[:stage_id] - ) - - flash.notice = "Administrateur créé" - redirect_to manager_demandes_path - else - flash.now.alert = administrateur.errors.full_messages.to_sentence - @pending_demandes = pending_demandes - render :index - end - end - - def refuse_administrateur - PipedriveRefusesDealsJob.perform_later( - refuse_administrateur_params[:person_id], - current_super_admin.id - ) - - AdministrationMailer - .refuse_admin(refuse_administrateur_params[:email]) - .deliver_later - - flash.notice = "La demande de #{refuse_administrateur_params[:email]} va être refusée" - redirect_to manager_demandes_path - end - - private - - def create_administrateur_params - params.permit(:email, :person_id, :stage_id) - end - - def refuse_administrateur_params - params.permit(:email, :person_id) - end - - def pending_demandes - already_approved_emails = Administrateur.eager_load(:user) - .where(users: { email: demandes.map { |d| d[:email] } }) - .map(&:email) - - demandes.reject { |demande| already_approved_emails.include?(demande[:email]) } - end - - def demandes - @demandes ||= PipedriveService.get_demandes - end - end -end diff --git a/app/controllers/procedures_controller.rb b/app/controllers/procedures_controller.rb new file mode 100644 index 000000000..860fc31f3 --- /dev/null +++ b/app/controllers/procedures_controller.rb @@ -0,0 +1,17 @@ +class ProceduresController < ApplicationController + before_action :retrieve_procedure + + def logo + if @procedure.logo.attached? + redirect_to url_for(@procedure.logo.variant(:email)) + else + redirect_to ActionController::Base.helpers.image_url(PROCEDURE_DEFAULT_LOGO_SRC) + end + end + + private + + def retrieve_procedure + @procedure = Procedure.find(params[:id]) + end +end diff --git a/app/controllers/users/commencer_controller.rb b/app/controllers/users/commencer_controller.rb index f825938cb..9f007c92b 100644 --- a/app/controllers/users/commencer_controller.rb +++ b/app/controllers/users/commencer_controller.rb @@ -20,6 +20,8 @@ module Users check_prefilled_dossier_ownership if @prefilled_dossier end + @usual_traitement_time = @procedure.stats_usual_traitement_time + render 'commencer/show' end @@ -94,7 +96,6 @@ module Users def build_prefilled_dossier @prefilled_dossier = Dossier.new( revision: @revision, - groupe_instructeur: @procedure.defaut_groupe_instructeur_for_new_dossier, state: Dossier.states.fetch(:brouillon), prefilled: true ) diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 4a28191b9..91419ad23 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -375,7 +375,6 @@ module Users dossier = Dossier.new( revision: params[:brouillon] ? procedure.draft_revision : procedure.active_revision, - groupe_instructeur: procedure.defaut_groupe_instructeur_for_new_dossier, user: current_user, state: Dossier.states.fetch(:brouillon) ) @@ -542,6 +541,7 @@ module Users def update_dossier_and_compute_errors errors = [] + @dossier.assign_attributes(champs_public_params) if @dossier.champs_public_all.any?(&:changed_for_autosave?) @dossier.last_champ_updated_at = Time.zone.now @@ -559,7 +559,6 @@ module Users @dossier.valid?(**submit_validation_options) errors += format_errors(errors: @dossier.errors) errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs) - errors end diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index 747646cdf..80564ef1e 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -6,7 +6,7 @@ class Users::SessionsController < Devise::SessionsController layout 'login', only: [:new, :create] before_action :restore_procedure_context, only: [:new, :create] - + skip_before_action :redirect_if_untrusted, only: [:reset_link_sent] # POST /resource/sign_in def create user = User.find_by(email: params[:user][:email]) @@ -18,6 +18,13 @@ class Users::SessionsController < Devise::SessionsController super end + def reset_link_sent + if send_login_token_or_bufferize(current_instructeur) + flash[:notice] = "Nous venons de vous renvoyer un nouveau lien de connexion sécurisée à #{APPLICATION_NAME}" + end + redirect_to link_sent_path(email: current_instructeur.email) + end + def link_sent if Devise.email_regexp.match?(params[:email]) @email = params[:email] diff --git a/app/dashboards/demande_dashboard.rb b/app/dashboards/demande_dashboard.rb deleted file mode 100644 index fbe725303..000000000 --- a/app/dashboards/demande_dashboard.rb +++ /dev/null @@ -1,4 +0,0 @@ -require "administrate/base_dashboard" - -class DemandeDashboard < Administrate::BaseDashboard -end diff --git a/app/dashboards/user_dashboard.rb b/app/dashboards/user_dashboard.rb index 5e9c13ebc..4a02aa844 100644 --- a/app/dashboards/user_dashboard.rb +++ b/app/dashboards/user_dashboard.rb @@ -13,6 +13,8 @@ class UserDashboard < Administrate::BaseDashboard confirmed?: Field::Boolean, created_at: Field::DateTime, updated_at: Field::DateTime, + blocked_at: Field::DateTime, + blocked_reason: Field::String, current_sign_in_at: Field::DateTime, dossiers: Field::HasMany }.freeze @@ -36,7 +38,9 @@ class UserDashboard < Administrate::BaseDashboard :email, :confirmed?, :current_sign_in_at, - :created_at + :created_at, + :blocked_at, + :blocked_reason ].freeze # FORM_ATTRIBUTES diff --git a/app/graphql/api/v2/context.rb b/app/graphql/api/v2/context.rb index 29613314f..22ccb3162 100644 --- a/app/graphql/api/v2/context.rb +++ b/app/graphql/api/v2/context.rb @@ -59,6 +59,7 @@ class API::V2::Context < GraphQL::Query::Context { graphql_query: query.query_string, graphql_variables: query.provided_variables&.to_json, + graphql_mutation: mutation?, graphql_null_error: errors.any? { _1.is_a? GraphQL::InvalidNullError }.presence, graphql_timeout_error: errors.any? { _1.is_a? GraphQL::Schema::Timeout::TimeoutError }.presence }.compact @@ -66,6 +67,12 @@ class API::V2::Context < GraphQL::Query::Context private + def mutation? + query.lookahead.selections.any? { _1.field.type.respond_to?(:mutation) }.presence + rescue + false + end + def compute_demarche_authorization(demarche) # procedure_ids and token are passed from graphql controller if self[:procedure_ids].present? @@ -73,6 +80,7 @@ class API::V2::Context < GraphQL::Query::Context elsif self[:token].present? token = APIToken.find_and_verify(self[:token], demarche.administrateurs) if token.present? + token.touch(:last_v2_authenticated_at) Current.user = token.administrateur.user true else diff --git a/app/graphql/api/v2/schema.rb b/app/graphql/api/v2/schema.rb index 89372aa15..93c62ef1e 100644 --- a/app/graphql/api/v2/schema.rb +++ b/app/graphql/api/v2/schema.rb @@ -138,7 +138,7 @@ class API::V2::Schema < GraphQL::Schema end end - use Timeout, max_seconds: 10 + use Timeout, max_seconds: 30 use GraphQL::Batch use GraphQL::Backtrace diff --git a/app/graphql/api/v2/stored_query.rb b/app/graphql/api/v2/stored_query.rb index 2ad9d408b..5650db3fb 100644 --- a/app/graphql/api/v2/stored_query.rb +++ b/app/graphql/api/v2/stored_query.rb @@ -43,6 +43,7 @@ class API::V2::StoredQuery $includeInstructeurs: Boolean = true $includeAvis: Boolean = false $includeMessages: Boolean = false + $includeCorrections: Boolean = false $includeGeometry: Boolean = false ) { demarche(number: $demarcheNumber) { @@ -135,6 +136,7 @@ class API::V2::StoredQuery $includeInstructeurs: Boolean = true $includeAvis: Boolean = false $includeMessages: Boolean = false + $includeCorrections: Boolean = false $includeGeometry: Boolean = false ) { groupeInstructeur(number: $groupeInstructeurNumber) { @@ -201,6 +203,7 @@ class API::V2::StoredQuery $includeInstructeurs: Boolean = true $includeAvis: Boolean = false $includeMessages: Boolean = false + $includeCorrections: Boolean = false $includeGeometry: Boolean = false ) { dossier(number: $dossierNumber) { @@ -239,6 +242,7 @@ class API::V2::StoredQuery } fragment DossierFragment on Dossier { + __typename id number archived @@ -250,6 +254,7 @@ class API::V2::StoredQuery dateTraitement dateExpiration dateSuppressionParUsager + dateDerniereCorrectionEnAttente @include(if: $includeCorrections) motivation motivationAttachment { ...FileFragment @@ -318,8 +323,8 @@ class API::V2::StoredQuery dateFermeture notice { url } deliberation { url } - demarcheUrl - cadreJuridiqueUrl + demarcheURL + cadreJuridiqueURL service @include(if: $includeService) { ...ServiceFragment } @@ -409,6 +414,10 @@ class API::V2::StoredQuery attachments { ...FileFragment } + correction @include(if: $includeCorrections) { + reason + dateResolution + } } fragment GeoAreaFragment on GeoArea { @@ -455,6 +464,7 @@ class API::V2::StoredQuery __typename label stringValue + updatedAt ... on DateChamp { date } @@ -584,11 +594,13 @@ class API::V2::StoredQuery fragment FileFragment on File { + __typename filename contentType checksum byteSize: byteSizeBigInt url + createdAt } fragment AddressFragment on Address { @@ -635,6 +647,7 @@ class API::V2::StoredQuery fragment PageInfoFragment on PageInfo { hasPreviousPage hasNextPage + startCursor endCursor } GRAPHQL diff --git a/app/graphql/extensions/attachment.rb b/app/graphql/extensions/attachment.rb index c0612d8fb..633d7a011 100644 --- a/app/graphql/extensions/attachment.rb +++ b/app/graphql/extensions/attachment.rb @@ -35,7 +35,7 @@ module Extensions # is a lazy value (e.g., a Promise – like in our case) def after_resolve(value:, **_rest) if value.respond_to?(:map) - attachments = value.map { after_resolve_attachment(_1) } + attachments = value.map { after_resolve_attachment(_1) }.compact if options[:as] == :single attachments.first diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql index 773df9474..e8cdf39b9 100644 --- a/app/graphql/schema.graphql +++ b/app/graphql/schema.graphql @@ -1066,7 +1066,8 @@ type DemarcheDescriptor { """ URL du cadre juridique qui justifie le droit de collecter les données demandées dans la démarche """ - cadreJuridiqueUrl: String + cadreJuridiqueURL: String + cadreJuridiqueUrl: String @deprecated(reason: "Utilisez le champ `cadreJuridiqueURL` à la place.") """ Date de la création. @@ -1106,7 +1107,8 @@ type DemarcheDescriptor { """ URL pour commencer la démarche """ - demarcheUrl: URL + demarcheURL: URL + demarcheUrl: URL @deprecated(reason: "Utilisez le champ `demarcheURL` à la place.") """ Description de la démarche. @@ -1116,7 +1118,8 @@ type DemarcheDescriptor { """ URL ou email pour contacter le Délégué à la Protection des Données (DPO) """ - dpoUrl: String + dpoURL: String + dpoUrl: String @deprecated(reason: "Utilisez le champ `dpoURL` à la place.") """ Durée de conservation des dossiers en mois. @@ -1129,7 +1132,8 @@ type DemarcheDescriptor { notice explicative de la démarche """ notice: File - noticeUrl: URL + noticeURL: URL + noticeUrl: URL @deprecated(reason: "Utilisez le champ `noticeURL` à la place.") """ Numero de la démarche. @@ -1142,7 +1146,8 @@ type DemarcheDescriptor { """ URL où les usagers trouvent le lien vers la démarche """ - siteWebUrl: String + siteWebURL: String + siteWebUrl: String @deprecated(reason: "Utilisez le champ `siteWebURL` à la place.") """ État de la démarche. diff --git a/app/graphql/types/demarche_descriptor_type.rb b/app/graphql/types/demarche_descriptor_type.rb index c9eff3c59..5645438af 100644 --- a/app/graphql/types/demarche_descriptor_type.rb +++ b/app/graphql/types/demarche_descriptor_type.rb @@ -25,6 +25,12 @@ Cela évite l’accès récursif aux dossiers." field :duree_conservation_dossiers, Int, "Durée de conservation des dossiers en mois.", null: false + field :demarcheUrl, Types::URL, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `demarcheURL` à la place.' + field :siteWebUrl, String, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `siteWebURL` à la place.' + field :dpoUrl, String, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `dpoURL` à la place.' + field :noticeUrl, Types::URL, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `noticeURL` à la place.' + field :cadreJuridiqueUrl, String, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `cadreJuridiqueURL` à la place.' + field :demarche_url, Types::URL, "URL pour commencer la démarche", null: true field :site_web_url, String, "URL où les usagers trouvent le lien vers la démarche", null: true field :dpo_url, String, "URL ou email pour contacter le Délégué à la Protection des Données (DPO)", null: true @@ -77,22 +83,27 @@ Cela évite l’accès récursif aux dossiers." def demarche_url Rails.application.routes.url_helpers.commencer_url(path: procedure.path) end + alias demarcheUrl demarche_url def dpo_url procedure.lien_dpo end + alias dpoUrl dpo_url def notice_url procedure.lien_notice end + alias noticeUrl notice_url def cadre_juridique_url procedure.cadre_juridique end + alias cadreJuridiqueUrl cadre_juridique_url def site_web_url procedure.lien_site_web end + alias siteWebUrl site_web_url def number procedure.id diff --git a/app/helpers/demande_helper.rb b/app/helpers/demande_helper.rb deleted file mode 100644 index 26266b204..000000000 --- a/app/helpers/demande_helper.rb +++ /dev/null @@ -1,21 +0,0 @@ -module DemandeHelper - def nb_of_procedures_options - { - 'je ne sais pas' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_DO_NOT_KNOW_VALUE, - '1' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_1_VALUE, - '1 à 10' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_1_TO_10_VALUE, - '10 à 100 ' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_10_TO_100_VALUE, - 'plus de 100' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_ABOVE_100_VALUE - } - end - - def deadline_options - { - 'le plus vite possible' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_ASAP_VALUE, - 'dans les 3 prochains mois' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NEXT_3_MONTHS_VALUE, - 'dans les 6 prochains mois' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NEXT_6_MONTHS_VALUE, - 'dans les 12 prochains mois' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NEXT_12_MONTHS_VALUE, - 'pas de date' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NO_DATE_VALUE - } - end -end diff --git a/app/helpers/procedure_helper.rb b/app/helpers/procedure_helper.rb index 2f9e5b76f..6b457c4dc 100644 --- a/app/helpers/procedure_helper.rb +++ b/app/helpers/procedure_helper.rb @@ -39,10 +39,10 @@ module ProcedureHelper end def can_send_groupe_message?(procedure) - procedure.dossiers - .state_brouillon - .includes(:groupe_instructeur) - .exists?(groupe_instructeur: current_instructeur.groupe_instructeurs) + groupe_instructeur_on_procedure_ids = procedure.groupe_instructeurs.active.ids.sort + groupe_instructeur_on_instructeur_ids = current_instructeur.groupe_instructeurs.active.where(procedure: procedure).ids.sort + + groupe_instructeur_on_procedure_ids == groupe_instructeur_on_instructeur_ids end def url_or_email_to_lien_dpo(procedure) diff --git a/app/jobs/pipedrive_accepts_deals_job.rb b/app/jobs/pipedrive_accepts_deals_job.rb deleted file mode 100644 index 05ce05a1c..000000000 --- a/app/jobs/pipedrive_accepts_deals_job.rb +++ /dev/null @@ -1,5 +0,0 @@ -class PipedriveAcceptsDealsJob < ApplicationJob - def perform(person_id, administration_id, stage_id) - PipedriveService.accept_demande_from_person(person_id, administration_id, stage_id) - end -end diff --git a/app/jobs/pipedrive_refuses_deals_job.rb b/app/jobs/pipedrive_refuses_deals_job.rb deleted file mode 100644 index 610a4cd51..000000000 --- a/app/jobs/pipedrive_refuses_deals_job.rb +++ /dev/null @@ -1,5 +0,0 @@ -class PipedriveRefusesDealsJob < ApplicationJob - def perform(person_id, administration_id) - PipedriveService.refuse_demande_from_person(person_id, administration_id) - end -end diff --git a/app/lib/biz_dev.rb b/app/lib/biz_dev.rb index 5543436ca..426687b0e 100644 --- a/app/lib/biz_dev.rb +++ b/app/lib/biz_dev.rb @@ -5,8 +5,4 @@ module BizDev def self.full_name(administration_id) NAME end - - def self.pipedrive_id(administration_id) - PIPEDRIVE_ID - end end diff --git a/app/lib/pipedrive/api.rb b/app/lib/pipedrive/api.rb deleted file mode 100644 index 2c4201e7f..000000000 --- a/app/lib/pipedrive/api.rb +++ /dev/null @@ -1,82 +0,0 @@ -class Pipedrive::API - PIPEDRIVE_ALL_NOT_DELETED_DEALS = 'all_not_deleted' - PIPEDRIVE_DEALS_URL = [PIPEDRIVE_API_URL, 'deals'].join("/") - PIPEDRIVE_PEOPLE_URL = [PIPEDRIVE_API_URL, 'persons'].join("/") - PIPEDRIVE_ORGANIZATIONS_URL = [PIPEDRIVE_API_URL, 'organizations'].join("/") - - def self.get_persons_owned_by_user(user_id) - url = PIPEDRIVE_PEOPLE_URL - params = { user_id: user_id } - - self.get(url, params) - end - - def self.get_deals_for_person(person_id) - url = [PIPEDRIVE_PEOPLE_URL, person_id, "deals"].join('/') - params = { status: PIPEDRIVE_ALL_NOT_DELETED_DEALS } - - self.get(url, params) - end - - def self.put_deal(deal_id, params) - url = [PIPEDRIVE_DEALS_URL, deal_id].join("/") - - self.put(url, params) - end - - def self.post_deal(params) - self.post(PIPEDRIVE_DEALS_URL, params) - end - - def self.put_person(person_id, params) - url = [PIPEDRIVE_PEOPLE_URL, person_id].join("/") - - self.put(url, params) - end - - def self.post_person(params) - self.post(PIPEDRIVE_PEOPLE_URL, params) - end - - def self.post_organization(params) - self.post(PIPEDRIVE_ORGANIZATIONS_URL, params) - end - - private - - def self.get(url, params) - params.merge!({ - start: 0, - limit: 500, - api_token: token - }) - - response = Typhoeus.get(url, params: params) - - if response.success? - JSON.parse(response.body)['data'] - end - end - - def self.put(url, params) - Typhoeus.put( - url, - params: { api_token: token }, - body: params.to_json, - headers: { 'content-type' => 'application/json' } - ) - end - - def self.post(url, params) - Typhoeus.post( - url, - params: { api_token: token }, - body: params.to_json, - headers: { 'content-type' => 'application/json' } - ) - end - - def self.token - Rails.application.secrets.pipedrive[:key] - end -end diff --git a/app/lib/pipedrive/deal_adapter.rb b/app/lib/pipedrive/deal_adapter.rb deleted file mode 100644 index 5e8cd77ef..000000000 --- a/app/lib/pipedrive/deal_adapter.rb +++ /dev/null @@ -1,63 +0,0 @@ -class Pipedrive::DealAdapter - PIPEDRIVE_ADMIN_CENTRAL_STOCK_STAGE_ID = 35 - PIPEDRIVE_SERVICE_DECO_REGIONAL_STOCK_STAGE_ID = 24 - PIPEDRIVE_SERVICE_DECO_DEPARTEMENTAL_STOCK_STAGE_ID = 20 - PIPEDRIVE_COLLECTIVITE_DEP_OU_REG_STOCK_STAGE_ID = 30 - PIPEDRIVE_COLLECTIVITE_LOCALE_STOCK_STAGE_ID = 40 - PIPEDRIVE_ORGANISMES_STOCK_STAGE_ID = 1 - PIPEDRIVE_ORGANISMES_REFUSES_STOCK_STAGE_ID = 45 - PIPEDRIVE_SUSPECTS_COMPTE_CREE_STAGE_ID = 48 - - PIPEDRIVE_LOST_STATUS = "lost" - PIPEDRIVE_LOST_REASON = "refusé depuis DS" - - PIPEDRIVE_NB_OF_PROCEDURES_ATTRIBUTE_ID = "b22f8710352a7fb548623c062bf82ed6d1b6b704" - PIPEDRIVE_NB_OF_PROCEDURES_DO_NOT_KNOW_VALUE = "Je ne sais pas" - PIPEDRIVE_NB_OF_PROCEDURES_1_VALUE = "juste 1" - PIPEDRIVE_NB_OF_PROCEDURES_1_TO_10_VALUE = "de 1 a 10" - PIPEDRIVE_NB_OF_PROCEDURES_10_TO_100_VALUE = "de 10 a 100" - PIPEDRIVE_NB_OF_PROCEDURES_ABOVE_100_VALUE = "Plus de 100" - - PIPEDRIVE_DEADLINE_ATTRIBUTE_ID = "36a72c82af9d9f0d476b041ede8876844a249bf2" - PIPEDRIVE_DEADLINE_ASAP_VALUE = "Le plus vite possible" - PIPEDRIVE_DEADLINE_NEXT_3_MONTHS_VALUE = "Dans les 3 prochain mois" - PIPEDRIVE_DEADLINE_NEXT_6_MONTHS_VALUE = "Dans les 6 prochain mois" - PIPEDRIVE_DEADLINE_NEXT_12_MONTHS_VALUE = "Dans les 12 prochain mois" - PIPEDRIVE_DEADLINE_NO_DATE_VALUE = "Pas de date" - - def self.refuse_deal(deal_id, owner_id) - params = { - user_id: owner_id, - stage_id: PIPEDRIVE_ORGANISMES_REFUSES_STOCK_STAGE_ID, - status: PIPEDRIVE_LOST_STATUS, - lost_reason: PIPEDRIVE_LOST_REASON - } - - Pipedrive::API.put_deal(deal_id, params) - end - - def self.get_deals_ids_for_person(person_id) - deals = Pipedrive::API.get_deals_for_person(person_id) || [] - deals.map { |datum| datum['id'] } - end - - def self.update_deal_owner_and_stage(deal_id, owner_id, stage_id) - params = { user_id: owner_id, stage_id: stage_id } - - Pipedrive::API.put_deal(deal_id, params) - end - - def self.add_deal(organisation_id, person_id, title, nb_of_procedures, nb_of_dossiers, deadline) - params = { - org_id: organisation_id, - person_id: person_id, - title: title, - user_id: Pipedrive::PersonAdapter::PIPEDRIVE_ROBOT_ID, - "#{PIPEDRIVE_NB_OF_PROCEDURES_ATTRIBUTE_ID}": nb_of_procedures, - value: nb_of_dossiers, - "#{PIPEDRIVE_DEADLINE_ATTRIBUTE_ID}": deadline - } - - Pipedrive::API.post_deal(params) - end -end diff --git a/app/lib/pipedrive/organization_adapter.rb b/app/lib/pipedrive/organization_adapter.rb deleted file mode 100644 index b4fb88ea1..000000000 --- a/app/lib/pipedrive/organization_adapter.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Pipedrive::OrganizationAdapter - def self.add_organization(name, address) - params = { - name: name, - owner_id: Pipedrive::PersonAdapter::PIPEDRIVE_ROBOT_ID, - address: address - } - - response = Pipedrive::API.post_organization(params) - - JSON.parse(response.body)['data']['id'] - end -end diff --git a/app/lib/pipedrive/person_adapter.rb b/app/lib/pipedrive/person_adapter.rb deleted file mode 100644 index 270dd223f..000000000 --- a/app/lib/pipedrive/person_adapter.rb +++ /dev/null @@ -1,52 +0,0 @@ -class Pipedrive::PersonAdapter - PIPEDRIVE_POSTE_ATTRIBUTE_ID = '33a790746f1713d712fe97bcce9ac1ca6374a4d6' - PIPEDRIVE_SOURCE_ATTRIBUTE_ID = '2fa7864f467ffa97721cbcd08df5a3d591b15f50' - PIPEDRIVE_NB_DOSSIERS_ATTRIBUTE_ID = '2734a3ff19f4b88bd0d7b4cf02c47c7545617207' - PIPEDRIVE_DEADLINE_ATTRIBUTE_ID = 'ef766dd14de7da246fb5fc1704f45d1f1830f6c9' - PIPEDRIVE_ROBOT_ID = '11381160' - - def self.get_demandes_from_persons_owned_by_robot - demandes = Pipedrive::API.get_persons_owned_by_user(PIPEDRIVE_ROBOT_ID) - - if demandes.present? - demandes.map do |datum| - { - person_id: datum['id'], - nom: datum['name'], - poste: datum[PIPEDRIVE_POSTE_ATTRIBUTE_ID], - email: datum.dig('email', 0, 'value'), - tel: datum.dig('phone', 0, 'value'), - organisation: datum['org_name'], - nb_dossiers: datum[PIPEDRIVE_NB_DOSSIERS_ATTRIBUTE_ID], - deadline: datum[PIPEDRIVE_DEADLINE_ATTRIBUTE_ID] - } - end - else - [] - end - end - - def self.update_person_owner(person_id, owner_id) - params = { owner_id: owner_id } - - Pipedrive::API.put_person(person_id, params) - end - - def self.add_person(email, phone, name, organization_id, poste, source, nb_of_dossiers, deadline) - params = { - email: email, - phone: phone, - name: name, - org_id: organization_id, - owner_id: PIPEDRIVE_ROBOT_ID, - "#{PIPEDRIVE_POSTE_ATTRIBUTE_ID}": poste, - "#{PIPEDRIVE_SOURCE_ATTRIBUTE_ID}": source, - "#{PIPEDRIVE_NB_DOSSIERS_ATTRIBUTE_ID}": nb_of_dossiers, - "#{PIPEDRIVE_DEADLINE_ATTRIBUTE_ID}": deadline - } - - response = Pipedrive::API.post_person(params) - - JSON.parse(response.body)['data']['id'] - end -end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 4577daf46..adb90e82d 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -8,18 +8,4 @@ class ApplicationMailer < ActionMailer::Base layout 'mailer' before_action -> { Sentry.set_tags(mailer: mailer_name, action: action_name) } - - # Attach the procedure logo to the email (if any). - # Returns the attachment url. - def attach_logo(procedure) - if procedure.logo.attached? - logo_filename = procedure.logo.filename.to_s - attachments.inline[logo_filename] = procedure.logo.download - attachments[logo_filename].url - end - rescue StandardError => e - # A problem occured when reading logo, maybe the logo is missing and we should clean the procedure to remove logo reference ? - Sentry.capture_exception(e, extra: { procedure_id: procedure.id }) - nil - end end diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index 27da3c9d7..d9081708e 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -12,7 +12,7 @@ class DossierMailer < ApplicationMailer @dossier = params[:dossier] I18n.with_locale(@dossier.user_locale) do @service = @dossier.procedure.service - @logo_url = attach_logo(@dossier.procedure) + @logo_url = procedure_logo_url(@dossier.procedure) @subject = default_i18n_subject(libelle_demarche: @dossier.procedure.libelle) mail(to: @dossier.user_email_for(:notification), subject: @subject) do |format| @@ -27,7 +27,7 @@ class DossierMailer < ApplicationMailer I18n.with_locale(dossier.user_locale) do @dossier = dossier @service = dossier.procedure.service - @logo_url = attach_logo(dossier.procedure) + @logo_url = procedure_logo_url(@dossier.procedure) @body = commentaire.body @subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle) @@ -52,7 +52,7 @@ class DossierMailer < ApplicationMailer I18n.with_locale(dossier.user_locale) do @dossier = dossier @service = dossier.procedure.service - @logo_url = attach_logo(dossier.procedure) + @logo_url = procedure_logo_url(@dossier.procedure) @correction = commentaire.dossier_correction @subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle) @@ -85,7 +85,7 @@ class DossierMailer < ApplicationMailer I18n.with_locale(dossier.user_locale) do @dossier = dossier @service = dossier.procedure.service - @logo_url = attach_logo(dossier.procedure) + @logo_url = procedure_logo_url(@dossier.procedure) @subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle) mail(to: dossier.user_email_for(:notification), subject: @subject) do |format| diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index d969295b8..23b9a6057 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -17,7 +17,7 @@ class NotificationMailer < ApplicationMailer def send_notification @service = @dossier.procedure.service - @logo_url = attach_logo(@dossier.procedure) + @logo_url = procedure_logo_url(@dossier.procedure) attachments[@attachment[:filename]] = @attachment[:content] if @attachment.present? I18n.with_locale(@dossier.user_locale) do mail(subject: @subject, to: @email, template_name: 'send_notification') diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index 819f9a15c..1c68711c0 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -1,12 +1,3 @@ -# == Schema Information -# -# Table name: administrateurs -# -# id :integer not null, primary key -# created_at :datetime -# updated_at :datetime -# user_id :bigint not null -# class Administrateur < ApplicationRecord UNUSED_ADMIN_THRESHOLD = ENV.fetch('UNUSED_ADMIN_THRESHOLD') { 6 }.to_i.months @@ -29,7 +20,10 @@ class Administrateur < ApplicationRecord .where.missing(:services) .left_outer_joins(:administrateurs_procedures) # needed to bypass procedure hidden default scope .where(administrateurs_procedures: { procedure_id: nil }) - .where("users.last_sign_in_at < ? ", UNUSED_ADMIN_THRESHOLD.ago) + .includes(:api_tokens) + .where(users: { last_sign_in_at: ..UNUSED_ADMIN_THRESHOLD.ago }) + .merge(APIToken.where(last_v1_authenticated_at: nil).or(APIToken.where(last_v1_authenticated_at: ..UNUSED_ADMIN_THRESHOLD.ago))) + .merge(APIToken.where(last_v2_authenticated_at: nil).or(APIToken.where(last_v2_authenticated_at: ..UNUSED_ADMIN_THRESHOLD.ago))) end def self.by_email(email) diff --git a/app/models/administrateurs_instructeur.rb b/app/models/administrateurs_instructeur.rb index f885c14ee..099f1bbc9 100644 --- a/app/models/administrateurs_instructeur.rb +++ b/app/models/administrateurs_instructeur.rb @@ -1,12 +1,3 @@ -# == Schema Information -# -# Table name: administrateurs_instructeurs -# -# created_at :datetime -# updated_at :datetime -# administrateur_id :integer not null -# instructeur_id :integer not null -# class AdministrateursInstructeur < ApplicationRecord belongs_to :administrateur belongs_to :instructeur diff --git a/app/models/administrateurs_procedure.rb b/app/models/administrateurs_procedure.rb index 1fd2002dc..084a18781 100644 --- a/app/models/administrateurs_procedure.rb +++ b/app/models/administrateurs_procedure.rb @@ -1,13 +1,3 @@ -# == Schema Information -# -# Table name: administrateurs_procedures -# -# manager :boolean -# created_at :datetime not null -# updated_at :datetime not null -# administrateur_id :bigint not null -# procedure_id :bigint not null -# class AdministrateursProcedure < ApplicationRecord belongs_to :administrateur belongs_to :procedure diff --git a/app/models/api_token.rb b/app/models/api_token.rb index a0e4a3ae5..4616969b8 100644 --- a/app/models/api_token.rb +++ b/app/models/api_token.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: api_tokens -# -# id :uuid not null, primary key -# allowed_procedure_ids :bigint is an Array -# encrypted_token :string not null -# name :string not null -# write_access :boolean default(TRUE), not null -# version :integer default(3), not null -# created_at :datetime not null -# updated_at :datetime not null -# administrateur_id :bigint not null -# class APIToken < ApplicationRecord include ActiveRecord::SecureToken diff --git a/app/models/archive.rb b/app/models/archive.rb index 0c7bd17cf..87eb4e461 100644 --- a/app/models/archive.rb +++ b/app/models/archive.rb @@ -1,15 +1,4 @@ # == Schema Information -# -# Table name: archives -# -# id :bigint not null, primary key -# job_status :string not null -# key :text not null -# month :date -# time_span_type :string not null -# created_at :datetime not null -# updated_at :datetime not null -# class Archive < ApplicationRecord include TransientModelsWithPurgeableJobConcern diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb index d49462b68..a2f178235 100644 --- a/app/models/assign_to.rb +++ b/app/models/assign_to.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: assign_tos -# -# id :integer not null, primary key -# daily_email_notifications_enabled :boolean default(FALSE), not null -# instant_email_dossier_notifications_enabled :boolean default(FALSE), not null -# instant_email_message_notifications_enabled :boolean default(FALSE), not null -# instant_expert_avis_email_notifications_enabled :boolean default(FALSE) -# manager :boolean default(FALSE) -# weekly_email_notifications_enabled :boolean default(TRUE), not null -# created_at :datetime -# updated_at :datetime -# groupe_instructeur_id :bigint -# instructeur_id :integer -# class AssignTo < ApplicationRecord belongs_to :instructeur, optional: false belongs_to :groupe_instructeur, optional: false diff --git a/app/models/attestation.rb b/app/models/attestation.rb index 9964a5f7a..1bb486633 100644 --- a/app/models/attestation.rb +++ b/app/models/attestation.rb @@ -1,13 +1,3 @@ -# == Schema Information -# -# Table name: attestations -# -# id :integer not null, primary key -# title :string -# created_at :datetime not null -# updated_at :datetime not null -# dossier_id :integer not null -# class Attestation < ApplicationRecord belongs_to :dossier, optional: false diff --git a/app/models/attestation_template.rb b/app/models/attestation_template.rb index 63c6b1cb4..8b1e9d792 100644 --- a/app/models/attestation_template.rb +++ b/app/models/attestation_template.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: attestation_templates -# -# id :integer not null, primary key -# activated :boolean -# body :text -# footer :text -# title :text -# created_at :datetime not null -# updated_at :datetime not null -# procedure_id :integer -# class AttestationTemplate < ApplicationRecord include ActionView::Helpers::NumberHelper include TagsSubstitutionConcern diff --git a/app/models/avis.rb b/app/models/avis.rb index 2cc17d25b..c8d3790d0 100644 --- a/app/models/avis.rb +++ b/app/models/avis.rb @@ -1,23 +1,3 @@ -# == Schema Information -# -# Table name: avis -# -# id :integer not null, primary key -# answer :text -# claimant_type :string -# confidentiel :boolean default(FALSE), not null -# email :string -# introduction :text -# question_answer :boolean -# question_label :string -# reminded_at :datetime -# revoked_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# claimant_id :integer not null -# dossier_id :integer -# experts_procedure_id :bigint -# class Avis < ApplicationRecord include EmailSanitizableConcern diff --git a/app/models/batch_operation.rb b/app/models/batch_operation.rb index 4c3e4e345..c1da424c3 100644 --- a/app/models/batch_operation.rb +++ b/app/models/batch_operation.rb @@ -1,20 +1,3 @@ -# == Schema Information -# -# Table name: batch_operations -# -# id :bigint not null, primary key -# failed_dossier_ids :bigint default([]), not null, is an Array -# finished_at :datetime -# operation :string not null -# payload :jsonb not null -# run_at :datetime -# seen_at :datetime -# success_dossier_ids :bigint default([]), not null, is an Array -# created_at :datetime not null -# updated_at :datetime not null -# instructeur_id :bigint not null -# - class BatchOperation < ApplicationRecord enum operation: { accepter: 'accepter', diff --git a/app/models/bill_signature.rb b/app/models/bill_signature.rb index 7c61d66e4..e5778a912 100644 --- a/app/models/bill_signature.rb +++ b/app/models/bill_signature.rb @@ -1,12 +1,3 @@ -# == Schema Information -# -# Table name: bill_signatures -# -# id :bigint not null, primary key -# digest :string -# created_at :datetime not null -# updated_at :datetime not null -# class BillSignature < ApplicationRecord has_many :dossier_operation_logs diff --git a/app/models/bulk_message.rb b/app/models/bulk_message.rb index f495e3510..8f54de120 100644 --- a/app/models/bulk_message.rb +++ b/app/models/bulk_message.rb @@ -1,18 +1,4 @@ -# == Schema Information -# -# Table name: bulk_messages -# -# id :bigint not null, primary key -# body :text not null -# dossier_count :integer -# dossier_state :string -# sent_at :datetime not null -# created_at :datetime not null -# updated_at :datetime not null -# instructeur_id :bigint not null -# class BulkMessage < ApplicationRecord belongs_to :instructeur has_and_belongs_to_many :groupe_instructeurs, -> { order(:label) } - has_one_attached :piece_jointe end diff --git a/app/models/champ.rb b/app/models/champ.rb index 81b0f2864..66a273319 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champ < ApplicationRecord include ChampConditionalConcern diff --git a/app/models/champs/address_champ.rb b/app/models/champs/address_champ.rb index a041d14fb..7f8c87ae6 100644 --- a/app/models/champs/address_champ.rb +++ b/app/models/champs/address_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::AddressChamp < Champs::TextChamp def full_address? data.present? diff --git a/app/models/champs/annuaire_education_champ.rb b/app/models/champs/annuaire_education_champ.rb index 46a3ee389..e691b707b 100644 --- a/app/models/champs/annuaire_education_champ.rb +++ b/app/models/champs/annuaire_education_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::AnnuaireEducationChamp < Champs::TextChamp def fetch_external_data? true diff --git a/app/models/champs/boolean_champ.rb b/app/models/champs/boolean_champ.rb index 5539369dc..f474944d7 100644 --- a/app/models/champs/boolean_champ.rb +++ b/app/models/champs/boolean_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::BooleanChamp < Champ TRUE_VALUE = 'true' FALSE_VALUE = 'false' diff --git a/app/models/champs/carte_champ.rb b/app/models/champs/carte_champ.rb index 208b72dfb..c3114388e 100644 --- a/app/models/champs/carte_champ.rb +++ b/app/models/champs/carte_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::CarteChamp < Champ # Default map location. Center of the World, ahm, France... DEFAULT_LON = 2.428462 diff --git a/app/models/champs/checkbox_champ.rb b/app/models/champs/checkbox_champ.rb index f8d5b72f5..dd67f7be0 100644 --- a/app/models/champs/checkbox_champ.rb +++ b/app/models/champs/checkbox_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::CheckboxChamp < Champs::BooleanChamp def for_export true? ? 'on' : 'off' diff --git a/app/models/champs/civilite_champ.rb b/app/models/champs/civilite_champ.rb index 1d25877a6..2f19c8009 100644 --- a/app/models/champs/civilite_champ.rb +++ b/app/models/champs/civilite_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::CiviliteChamp < Champ validates :value, inclusion: ["M.", "Mme"], allow_nil: true, allow_blank: false diff --git a/app/models/champs/cnaf_champ.rb b/app/models/champs/cnaf_champ.rb index c3ac55170..2ddb6586f 100644 --- a/app/models/champs/cnaf_champ.rb +++ b/app/models/champs/cnaf_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::CnafChamp < Champs::TextChamp # see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/cnaf-input-validation.middleware.ts validates :numero_allocataire, format: { with: /\A\d{1,7}\z/ }, if: -> { code_postal.present? && validation_context != :brouillon } diff --git a/app/models/champs/commune_champ.rb b/app/models/champs/commune_champ.rb index 9dafdc4d5..9b9ca0335 100644 --- a/app/models/champs/commune_champ.rb +++ b/app/models/champs/commune_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::CommuneChamp < Champs::TextChamp store_accessor :value_json, :code_departement, :code_postal before_validation :on_code_postal_change diff --git a/app/models/champs/date_champ.rb b/app/models/champs/date_champ.rb index f6fcea185..10fa8602c 100644 --- a/app/models/champs/date_champ.rb +++ b/app/models/champs/date_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::DateChamp < Champ before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill } validate :iso_8601 diff --git a/app/models/champs/datetime_champ.rb b/app/models/champs/datetime_champ.rb index 6e8ed59cc..08a4c4719 100644 --- a/app/models/champs/datetime_champ.rb +++ b/app/models/champs/datetime_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::DatetimeChamp < Champ before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill } validate :iso_8601 @@ -66,6 +44,6 @@ class Champs::DatetimeChamp < Champ end def valid_iso8601? - /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}\+\d{2}:\d{2})?$/.match?(value) + /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}[\+\-]\d{2}:\d{2})?$/.match?(value) end end diff --git a/app/models/champs/decimal_number_champ.rb b/app/models/champs/decimal_number_champ.rb index e6f66be76..31278e52a 100644 --- a/app/models/champs/decimal_number_champ.rb +++ b/app/models/champs/decimal_number_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::DecimalNumberChamp < Champ validates :value, numericality: { allow_nil: true, diff --git a/app/models/champs/departement_champ.rb b/app/models/champs/departement_champ.rb index 5a99ce8ad..1447ec193 100644 --- a/app/models/champs/departement_champ.rb +++ b/app/models/champs/departement_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::DepartementChamp < Champs::TextChamp validate :value_in_departement_names, unless: -> { value.nil? } validate :external_id_in_departement_codes, unless: -> { external_id.nil? } diff --git a/app/models/champs/dgfip_champ.rb b/app/models/champs/dgfip_champ.rb index 5c84c1b43..832897518 100644 --- a/app/models/champs/dgfip_champ.rb +++ b/app/models/champs/dgfip_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::DgfipChamp < Champs::TextChamp # see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/dgfip-input-validation.middleware.ts validates :numero_fiscal, format: { with: /\A\w{13,14}\z/ }, if: -> { reference_avis.present? && validation_context != :brouillon } diff --git a/app/models/champs/dossier_link_champ.rb b/app/models/champs/dossier_link_champ.rb index 00c7f8869..ba73ddce6 100644 --- a/app/models/champs/dossier_link_champ.rb +++ b/app/models/champs/dossier_link_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::DossierLinkChamp < Champ validate :value_integerable, if: -> { value.present? }, on: :prefill diff --git a/app/models/champs/drop_down_list_champ.rb b/app/models/champs/drop_down_list_champ.rb index 467643673..5e1e86722 100644 --- a/app/models/champs/drop_down_list_champ.rb +++ b/app/models/champs/drop_down_list_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::DropDownListChamp < Champ store_accessor :value_json, :other THRESHOLD_NB_OPTIONS_AS_RADIO = 5 diff --git a/app/models/champs/email_champ.rb b/app/models/champs/email_champ.rb index 0c17ea122..5f5f36104 100644 --- a/app/models/champs/email_champ.rb +++ b/app/models/champs/email_champ.rb @@ -1,24 +1,2 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::EmailChamp < Champs::TextChamp end diff --git a/app/models/champs/epci_champ.rb b/app/models/champs/epci_champ.rb index 0607cf67e..3b65f864f 100644 --- a/app/models/champs/epci_champ.rb +++ b/app/models/champs/epci_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::EpciChamp < Champs::TextChamp store_accessor :value_json, :code_departement before_validation :on_departement_change diff --git a/app/models/champs/explication_champ.rb b/app/models/champs/explication_champ.rb index c81759dd2..d15bd2e1d 100644 --- a/app/models/champs/explication_champ.rb +++ b/app/models/champs/explication_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::ExplicationChamp < Champs::TextChamp def search_terms # The user cannot enter any information here so it doesn’t make much sense to search diff --git a/app/models/champs/header_section_champ.rb b/app/models/champs/header_section_champ.rb index 03efd51d8..69ac6d54c 100644 --- a/app/models/champs/header_section_champ.rb +++ b/app/models/champs/header_section_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::HeaderSectionChamp < Champ def level if parent.present? diff --git a/app/models/champs/iban_champ.rb b/app/models/champs/iban_champ.rb index 9e40cd3f2..577dbc09c 100644 --- a/app/models/champs/iban_champ.rb +++ b/app/models/champs/iban_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::IbanChamp < Champ validates_with IbanValidator, if: -> { validation_context != :brouillon } after_validation :format_iban diff --git a/app/models/champs/integer_number_champ.rb b/app/models/champs/integer_number_champ.rb index 29ca29e05..b78af269c 100644 --- a/app/models/champs/integer_number_champ.rb +++ b/app/models/champs/integer_number_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::IntegerNumberChamp < Champ validates :value, numericality: { only_integer: true, diff --git a/app/models/champs/linked_drop_down_list_champ.rb b/app/models/champs/linked_drop_down_list_champ.rb index 31a44c32c..0033a0a70 100644 --- a/app/models/champs/linked_drop_down_list_champ.rb +++ b/app/models/champs/linked_drop_down_list_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::LinkedDropDownListChamp < Champ delegate :primary_options, :secondary_options, to: 'type_de_champ.dynamic_type' diff --git a/app/models/champs/mesri_champ.rb b/app/models/champs/mesri_champ.rb index 82df2db85..d12bc3c59 100644 --- a/app/models/champs/mesri_champ.rb +++ b/app/models/champs/mesri_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::MesriChamp < Champs::TextChamp # see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/mesri-input-validation.middleware.ts store_accessor :value_json, :ine diff --git a/app/models/champs/multiple_drop_down_list_champ.rb b/app/models/champs/multiple_drop_down_list_champ.rb index 7b4d2d99a..9484ebe5e 100644 --- a/app/models/champs/multiple_drop_down_list_champ.rb +++ b/app/models/champs/multiple_drop_down_list_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::MultipleDropDownListChamp < Champ validate :values_are_in_options, if: -> { value.present? } diff --git a/app/models/champs/number_champ.rb b/app/models/champs/number_champ.rb index 320aa22e7..8903284e2 100644 --- a/app/models/champs/number_champ.rb +++ b/app/models/champs/number_champ.rb @@ -1,24 +1,2 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::NumberChamp < Champ end diff --git a/app/models/champs/pays_champ.rb b/app/models/champs/pays_champ.rb index b00402850..5029deea6 100644 --- a/app/models/champs/pays_champ.rb +++ b/app/models/champs/pays_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::PaysChamp < Champs::TextChamp validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: true, allow_blank: false validates :external_id, inclusion: APIGeoService.countries.pluck(:code), allow_nil: true, allow_blank: false diff --git a/app/models/champs/phone_champ.rb b/app/models/champs/phone_champ.rb index 3e0c978f4..1d44152ad 100644 --- a/app/models/champs/phone_champ.rb +++ b/app/models/champs/phone_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::PhoneChamp < Champs::TextChamp # We want to allow: # * international (e164) phone numbers diff --git a/app/models/champs/piece_justificative_champ.rb b/app/models/champs/piece_justificative_champ.rb index e95af2bf5..0ccbb83d7 100644 --- a/app/models/champs/piece_justificative_champ.rb +++ b/app/models/champs/piece_justificative_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::PieceJustificativeChamp < Champ FILE_MAX_SIZE = 200.megabytes diff --git a/app/models/champs/pole_emploi_champ.rb b/app/models/champs/pole_emploi_champ.rb index 1d9951d1c..e7cfde785 100644 --- a/app/models/champs/pole_emploi_champ.rb +++ b/app/models/champs/pole_emploi_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::PoleEmploiChamp < Champs::TextChamp # see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/pole-emploi-input-validation.middleware.ts store_accessor :value_json, :identifiant diff --git a/app/models/champs/region_champ.rb b/app/models/champs/region_champ.rb index a842b577a..5e2c60b05 100644 --- a/app/models/champs/region_champ.rb +++ b/app/models/champs/region_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::RegionChamp < Champs::TextChamp validate :value_in_region_names, unless: -> { value.nil? } validate :external_id_in_region_codes, unless: -> { external_id.nil? } diff --git a/app/models/champs/repetition_champ.rb b/app/models/champs/repetition_champ.rb index d2dc460bc..ed9d91c00 100644 --- a/app/models/champs/repetition_champ.rb +++ b/app/models/champs/repetition_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::RepetitionChamp < Champ accepts_nested_attributes_for :champs delegate :libelle_for_export, to: :type_de_champ diff --git a/app/models/champs/rna_champ.rb b/app/models/champs/rna_champ.rb index 5bf7c78f0..3e521dd88 100644 --- a/app/models/champs/rna_champ.rb +++ b/app/models/champs/rna_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::RNAChamp < Champ include RNAChampAssociationFetchableConcern diff --git a/app/models/champs/siret_champ.rb b/app/models/champs/siret_champ.rb index 0901c3227..54c350544 100644 --- a/app/models/champs/siret_champ.rb +++ b/app/models/champs/siret_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::SiretChamp < Champ include SiretChampEtablissementFetchableConcern diff --git a/app/models/champs/text_champ.rb b/app/models/champs/text_champ.rb index 6a49e6a3e..8e24252ce 100644 --- a/app/models/champs/text_champ.rb +++ b/app/models/champs/text_champ.rb @@ -1,24 +1,2 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::TextChamp < Champ end diff --git a/app/models/champs/textarea_champ.rb b/app/models/champs/textarea_champ.rb index 24a744c59..289289c57 100644 --- a/app/models/champs/textarea_champ.rb +++ b/app/models/champs/textarea_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::TextareaChamp < Champs::TextChamp def for_export value.present? ? ActionView::Base.full_sanitizer.sanitize(value) : nil diff --git a/app/models/champs/titre_identite_champ.rb b/app/models/champs/titre_identite_champ.rb index c9c925d97..a24d7bef2 100644 --- a/app/models/champs/titre_identite_champ.rb +++ b/app/models/champs/titre_identite_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::TitreIdentiteChamp < Champ FILE_MAX_SIZE = 20.megabytes ACCEPTED_FORMATS = ['image/png', 'image/jpeg'] diff --git a/app/models/champs/yes_no_champ.rb b/app/models/champs/yes_no_champ.rb index 1d47a671e..3b814e295 100644 --- a/app/models/champs/yes_no_champ.rb +++ b/app/models/champs/yes_no_champ.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: champs -# -# id :integer not null, primary key -# data :jsonb -# fetch_external_data_exceptions :string is an Array -# prefilled :boolean default(FALSE) -# private :boolean default(FALSE), not null -# rebased_at :datetime -# type :string -# value :string -# value_json :jsonb -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# etablissement_id :integer -# external_id :string -# parent_id :bigint -# row_id :string -# type_de_champ_id :integer -# class Champs::YesNoChamp < Champs::BooleanChamp def yes_input_id "#{input_id}-yes" diff --git a/app/models/commentaire.rb b/app/models/commentaire.rb index 99e086747..4edbb0110 100644 --- a/app/models/commentaire.rb +++ b/app/models/commentaire.rb @@ -1,22 +1,6 @@ -# == Schema Information -# -# Table name: commentaires -# -# id :integer not null, primary key -# body :string -# discarded_at :datetime -# email :string -# created_at :datetime not null -# updated_at :datetime not null -# dossier_id :integer -# expert_id :bigint -# instructeur_id :bigint -# class Commentaire < ApplicationRecord include Discard::Model - belongs_to :dossier, inverse_of: :commentaires, touch: true, optional: false - belongs_to :instructeur, inverse_of: :commentaires, optional: true belongs_to :expert, inverse_of: :commentaires, optional: true has_one :dossier_correction, inverse_of: :commentaire, dependent: :nullify diff --git a/app/models/concerns/dossier_clone_concern.rb b/app/models/concerns/dossier_clone_concern.rb index fc056c8bd..914c6fc03 100644 --- a/app/models/concerns/dossier_clone_concern.rb +++ b/app/models/concerns/dossier_clone_concern.rb @@ -76,7 +76,8 @@ module DossierCloneConcern end def clone(user: nil, fork: false) - dossier_attributes = [:autorisation_donnees, :revision_id, :groupe_instructeur_id] + dossier_attributes = [:autorisation_donnees, :revision_id] + dossier_attributes += [:groupe_instructeur_id] if fork relationships = [:individual, :etablissement] cloned_champs = champs @@ -95,7 +96,6 @@ module DossierCloneConcern kopy.user = user || original.user kopy.state = Dossier.states.fetch(:brouillon) - kopy.champs = cloned_champs.values.map do |(_, champ)| champ.dossier = kopy champ.parent = cloned_champs[champ.parent_id].second if champ.child? diff --git a/app/models/concerns/trusted_device_concern.rb b/app/models/concerns/trusted_device_concern.rb index 07493f85b..2aa895893 100644 --- a/app/models/concerns/trusted_device_concern.rb +++ b/app/models/concerns/trusted_device_concern.rb @@ -19,8 +19,11 @@ module TrustedDeviceConcern def send_login_token_or_bufferize(instructeur) if !instructeur.young_login_token? - login_token = instructeur.create_trusted_device_token - InstructeurMailer.send_login_token(instructeur, login_token).deliver_later + token = instructeur.create_trusted_device_token + InstructeurMailer.send_login_token(instructeur, token).deliver_later + true + else + false end end diff --git a/app/models/deleted_dossier.rb b/app/models/deleted_dossier.rb index edb9632ac..b415a7709 100644 --- a/app/models/deleted_dossier.rb +++ b/app/models/deleted_dossier.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: deleted_dossiers -# -# id :bigint not null, primary key -# deleted_at :datetime -# reason :string -# state :string -# created_at :datetime not null -# updated_at :datetime not null -# dossier_id :bigint -# groupe_instructeur_id :bigint -# procedure_id :bigint -# revision_id :bigint -# user_id :bigint -# class DeletedDossier < ApplicationRecord belongs_to :procedure, -> { with_discarded }, inverse_of: :deleted_dossiers, optional: false belongs_to :groupe_instructeur, inverse_of: :deleted_dossiers, optional: true diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 8714a8343..ad918b743 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -1,54 +1,3 @@ -# == Schema Information -# -# Table name: dossiers -# -# id :integer not null, primary key -# api_entreprise_job_exceptions :string is an Array -# archived :boolean default(FALSE) -# archived_at :datetime -# archived_by :string -# autorisation_donnees :boolean -# brouillon_close_to_expiration_notice_sent_at :datetime -# conservation_extension :interval default(0 seconds) -# declarative_triggered_at :datetime -# deleted_user_email_never_send :string -# depose_at :datetime -# en_construction_at :datetime -# en_construction_close_to_expiration_notice_sent_at :datetime -# en_instruction_at :datetime -# for_procedure_preview :boolean default(FALSE) -# forced_groupe_instructeur :boolean -# groupe_instructeur_updated_at :datetime -# hidden_at :datetime -# hidden_by_administration_at :datetime -# hidden_by_reason :string -# hidden_by_user_at :datetime -# identity_updated_at :datetime -# last_avis_updated_at :datetime -# last_champ_private_updated_at :datetime -# last_champ_updated_at :datetime -# last_commentaire_updated_at :datetime -# migrated_champ_routage :boolean -# motivation :text -# prefill_token :string -# prefilled :boolean -# private_search_terms :string -# processed_at :datetime -# search_terms :string -# state :string -# sva_svr_decision_on :date -# sva_svr_decision_triggered_at :datetime -# termine_close_to_expiration_notice_sent_at :datetime -# created_at :datetime -# updated_at :datetime -# batch_operation_id :bigint -# dossier_transfer_id :bigint -# editing_fork_origin_id :bigint -# groupe_instructeur_id :bigint -# parent_dossier_id :bigint -# revision_id :bigint -# user_id :integer -# class Dossier < ApplicationRecord include DossierCloneConcern include DossierCorrectableConcern @@ -58,8 +7,6 @@ class Dossier < ApplicationRecord include DossierSearchableConcern include DossierSectionsConcern - self.ignored_columns += [:migrated_champ_routage] - enum state: { brouillon: 'brouillon', en_construction: 'en_construction', @@ -268,7 +215,7 @@ class Dossier < ApplicationRecord } scope :for_procedure_preview, -> { where(for_procedure_preview: true) } scope :for_editing_fork, -> { where.not(editing_fork_origin_id: nil) } - + scope :for_groupe_instructeur, -> (groupe_instructeurs) { where(groupe_instructeur: groupe_instructeurs) } scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) } scope :order_by_created_at, -> (order = :asc) { order(depose_at: order, created_at: order, id: order) } scope :updated_since, -> (since) { where('dossiers.updated_at >= ?', since) } @@ -905,7 +852,6 @@ class Dossier < ApplicationRecord .passer_en_construction .processed_at save! - MailTemplatePresenterService.create_commentaire_for_state(self) NotificationMailer.send_en_construction_notification(self).deliver_later procedure.compute_dossiers_count diff --git a/app/models/dossier_assignment.rb b/app/models/dossier_assignment.rb index 46917e188..90c517ad2 100644 --- a/app/models/dossier_assignment.rb +++ b/app/models/dossier_assignment.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: dossier_assignments -# -# id :bigint not null, primary key -# assigned_at :datetime not null -# assigned_by :string -# groupe_instructeur_label :string -# mode :string not null -# previous_groupe_instructeur_label :string -# dossier_id :bigint not null -# groupe_instructeur_id :bigint -# previous_groupe_instructeur_id :bigint -# class DossierAssignment < ApplicationRecord belongs_to :dossier diff --git a/app/models/dossier_batch_operation.rb b/app/models/dossier_batch_operation.rb index d126de57c..ca5582d22 100644 --- a/app/models/dossier_batch_operation.rb +++ b/app/models/dossier_batch_operation.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: dossier_batch_operations -# -# id :bigint not null, primary key -# state :string default("pending"), not null -# created_at :datetime not null -# updated_at :datetime not null -# batch_operation_id :bigint not null -# dossier_id :bigint not null -# class DossierBatchOperation < ApplicationRecord belongs_to :dossier belongs_to :batch_operation diff --git a/app/models/dossier_correction.rb b/app/models/dossier_correction.rb index c2ff19b13..001da4f75 100644 --- a/app/models/dossier_correction.rb +++ b/app/models/dossier_correction.rb @@ -1,21 +1,7 @@ -# == Schema Information -# -# Table name: dossier_corrections -# -# id :bigint not null, primary key -# reason :string default("incorrect"), not null -# resolved_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# commentaire_id :bigint -# dossier_id :bigint not null -# class DossierCorrection < ApplicationRecord belongs_to :dossier belongs_to :commentaire - self.ignored_columns += ['kind'] - validates_associated :commentaire scope :pending, -> { where(resolved_at: nil) } diff --git a/app/models/dossier_operation_log.rb b/app/models/dossier_operation_log.rb index 3fa2072d6..902626a85 100644 --- a/app/models/dossier_operation_log.rb +++ b/app/models/dossier_operation_log.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: dossier_operation_logs -# -# id :bigint not null, primary key -# automatic_operation :boolean default(FALSE), not null -# data :jsonb -# digest :text -# executed_at :datetime -# keep_until :datetime -# operation :string not null -# created_at :datetime not null -# updated_at :datetime not null -# bill_signature_id :bigint -# dossier_id :bigint -# class DossierOperationLog < ApplicationRecord enum operation: { changer_groupe_instructeur: 'changer_groupe_instructeur', diff --git a/app/models/dossier_submitted_message.rb b/app/models/dossier_submitted_message.rb index 01238804c..c87e7c10b 100644 --- a/app/models/dossier_submitted_message.rb +++ b/app/models/dossier_submitted_message.rb @@ -1,12 +1,3 @@ -# == Schema Information -# -# Table name: dossier_submitted_messages -# -# id :bigint not null, primary key -# message_on_submit_by_usager :string -# created_at :datetime not null -# updated_at :datetime not null -# class DossierSubmittedMessage < ApplicationRecord has_many :revisions, class_name: 'ProcedureRevision', inverse_of: :dossier_submitted_message, dependent: :nullify end diff --git a/app/models/dossier_transfer.rb b/app/models/dossier_transfer.rb index 15c77d845..502801e21 100644 --- a/app/models/dossier_transfer.rb +++ b/app/models/dossier_transfer.rb @@ -1,12 +1,3 @@ -# == Schema Information -# -# Table name: dossier_transfers -# -# id :bigint not null, primary key -# email :string not null -# created_at :datetime not null -# updated_at :datetime not null -# class DossierTransfer < ApplicationRecord include EmailSanitizableConcern has_many :dossiers, dependent: :nullify diff --git a/app/models/dossier_transfer_log.rb b/app/models/dossier_transfer_log.rb index f551b608f..574a7bfb0 100644 --- a/app/models/dossier_transfer_log.rb +++ b/app/models/dossier_transfer_log.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: dossier_transfer_logs -# -# id :bigint not null, primary key -# from :string not null -# to :string not null -# created_at :datetime not null -# updated_at :datetime not null -# dossier_id :bigint not null -# class DossierTransferLog < ApplicationRecord belongs_to :dossier end diff --git a/app/models/email_event.rb b/app/models/email_event.rb index 89e6e64ee..26f066e62 100644 --- a/app/models/email_event.rb +++ b/app/models/email_event.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: email_events -# -# id :bigint not null, primary key -# method :string not null -# processed_at :datetime -# status :string not null -# subject :string not null -# to :string not null -# created_at :datetime not null -# updated_at :datetime not null -# message_id :string -# class EmailEvent < ApplicationRecord RETENTION_DURATION = 1.month diff --git a/app/models/etablissement.rb b/app/models/etablissement.rb index ef3b47d6c..8937ad62e 100644 --- a/app/models/etablissement.rb +++ b/app/models/etablissement.rb @@ -1,52 +1,3 @@ -# == Schema Information -# -# Table name: etablissements -# -# id :integer not null, primary key -# adresse :string -# association_date_creation :date -# association_date_declaration :date -# association_date_publication :date -# association_objet :text -# association_rna :string -# association_titre :string -# code_insee_localite :string -# code_postal :string -# complement_adresse :string -# diffusable_commercialement :boolean -# enseigne :string -# entreprise_bilans_bdf :jsonb -# entreprise_bilans_bdf_monnaie :string -# entreprise_capital_social :bigint -# entreprise_code_effectif_entreprise :string -# entreprise_date_creation :date -# entreprise_effectif_annee :string -# entreprise_effectif_annuel :decimal(, ) -# entreprise_effectif_annuel_annee :string -# entreprise_effectif_mensuel :decimal(, ) -# entreprise_effectif_mois :string -# entreprise_etat_administratif :string -# entreprise_forme_juridique :string -# entreprise_forme_juridique_code :string -# entreprise_nom :string -# entreprise_nom_commercial :string -# entreprise_numero_tva_intracommunautaire :string -# entreprise_prenom :string -# entreprise_raison_sociale :string -# entreprise_siren :string -# entreprise_siret_siege_social :string -# libelle_naf :string -# localite :string -# naf :string -# nom_voie :string -# numero_voie :string -# siege_social :boolean -# siret :string -# type_voie :string -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# class Etablissement < ApplicationRecord belongs_to :dossier, optional: true diff --git a/app/models/exercice.rb b/app/models/exercice.rb index 6aba88c47..12169a663 100644 --- a/app/models/exercice.rb +++ b/app/models/exercice.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: exercices -# -# id :integer not null, primary key -# ca :string -# dateFinExercice :datetime -# date_fin_exercice :datetime -# date_fin_exercice_timestamp :integer -# created_at :datetime -# updated_at :datetime -# etablissement_id :integer -# class Exercice < ApplicationRecord belongs_to :etablissement, optional: false diff --git a/app/models/expert.rb b/app/models/expert.rb index 44c7d58ed..d86b69194 100644 --- a/app/models/expert.rb +++ b/app/models/expert.rb @@ -1,12 +1,3 @@ -# == Schema Information -# -# Table name: experts -# -# id :bigint not null, primary key -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# class Expert < ApplicationRecord belongs_to :user has_many :experts_procedures diff --git a/app/models/experts_procedure.rb b/app/models/experts_procedure.rb index 438086376..41c58594f 100644 --- a/app/models/experts_procedure.rb +++ b/app/models/experts_procedure.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: experts_procedures -# -# id :bigint not null, primary key -# allow_decision_access :boolean default(FALSE), not null -# revoked_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# expert_id :bigint not null -# procedure_id :bigint not null -# class ExpertsProcedure < ApplicationRecord belongs_to :expert belongs_to :procedure diff --git a/app/models/export.rb b/app/models/export.rb index d9f3b4c8d..f5fcab31c 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: exports -# -# id :bigint not null, primary key -# format :string not null -# job_status :string default("pending"), not null -# key :text not null -# procedure_presentation_snapshot :jsonb -# statut :string default("tous") -# time_span_type :string default("everything"), not null -# created_at :datetime not null -# updated_at :datetime not null -# procedure_presentation_id :bigint -# class Export < ApplicationRecord include TransientModelsWithPurgeableJobConcern diff --git a/app/models/follow.rb b/app/models/follow.rb index 28710ecf3..1ec50e371 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: follows -# -# id :integer not null, primary key -# annotations_privees_seen_at :datetime not null -# avis_seen_at :datetime not null -# demande_seen_at :datetime not null -# messagerie_seen_at :datetime not null -# unfollowed_at :datetime -# created_at :datetime -# updated_at :datetime -# dossier_id :integer not null -# instructeur_id :integer not null -# class Follow < ApplicationRecord belongs_to :instructeur, optional: false belongs_to :dossier, optional: false diff --git a/app/models/france_connect_information.rb b/app/models/france_connect_information.rb index c41bef39f..2acace8a7 100644 --- a/app/models/france_connect_information.rb +++ b/app/models/france_connect_information.rb @@ -1,22 +1,3 @@ -# == Schema Information -# -# Table name: france_connect_informations -# -# id :integer not null, primary key -# birthdate :date -# birthplace :string -# data :jsonb -# email_france_connect :string -# family_name :string -# gender :string -# given_name :string -# merge_token :string -# merge_token_created_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# france_connect_particulier_id :string -# user_id :integer -# class FranceConnectInformation < ApplicationRecord MERGE_VALIDITY = 15.minutes diff --git a/app/models/geo_area.rb b/app/models/geo_area.rb index 22a40fa00..e34669759 100644 --- a/app/models/geo_area.rb +++ b/app/models/geo_area.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: geo_areas -# -# id :bigint not null, primary key -# geometry :jsonb -# properties :jsonb -# source :string -# created_at :datetime -# updated_at :datetime -# champ_id :bigint -# geo_reference_id :string -# class GeoArea < ApplicationRecord include ActionView::Helpers::NumberHelper belongs_to :champ, optional: false diff --git a/app/models/groupe_instructeur.rb b/app/models/groupe_instructeur.rb index 7acf19561..69dc0ea2e 100644 --- a/app/models/groupe_instructeur.rb +++ b/app/models/groupe_instructeur.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: groupe_instructeurs -# -# id :bigint not null, primary key -# closed :boolean default(FALSE) -# label :text not null -# routing_rule :jsonb -# created_at :datetime not null -# updated_at :datetime not null -# procedure_id :bigint not null -# class GroupeInstructeur < ApplicationRecord include Logic DEFAUT_LABEL = 'défaut' @@ -42,7 +30,7 @@ class GroupeInstructeur < ApplicationRecord scope :for_api_v2, -> { includes(procedure: [:administrateurs]) } scope :active, -> { where(closed: false) } scope :closed, -> { where(closed: true) } - + scope :for_dossiers, -> (dossiers) { joins(:dossiers).where(dossiers: dossiers).distinct(:id) } def add(instructeur) return if instructeur.nil? return if in?(instructeur.groupe_instructeurs) @@ -117,7 +105,14 @@ class GroupeInstructeur < ApplicationRecord def routing_rule_matches_tdc? routing_tdc = procedure.active_revision.types_de_champ.find_by(stable_id: routing_rule.left.stable_id) - routing_rule.right.value.in?(routing_tdc.options['drop_down_options']) + + options = case routing_tdc.type_champ + when TypeDeChamp.type_champs.fetch(:departements) + APIGeoService.departements.map { _1[:code] } + when TypeDeChamp.type_champs.fetch(:drop_down_list) + routing_tdc.options_with_drop_down_other + end + routing_rule.right.value.in?(options) end serialize :routing_rule, LogicSerializer diff --git a/app/models/individual.rb b/app/models/individual.rb index f58f83639..7f1c40c86 100644 --- a/app/models/individual.rb +++ b/app/models/individual.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: individuals -# -# id :integer not null, primary key -# birthdate :date -# gender :string -# nom :string -# prenom :string -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# class Individual < ApplicationRecord belongs_to :dossier, optional: false diff --git a/app/models/instructeur.rb b/app/models/instructeur.rb index c6685b57c..5a5f92b16 100644 --- a/app/models/instructeur.rb +++ b/app/models/instructeur.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: instructeurs -# -# id :integer not null, primary key -# bypass_email_login_token :boolean default(FALSE), not null -# encrypted_login_token :text -# login_token_created_at :datetime -# created_at :datetime -# updated_at :datetime -# agent_connect_id :string -# user_id :bigint not null -# class Instructeur < ApplicationRecord has_and_belongs_to_many :administrateurs diff --git a/app/models/invite.rb b/app/models/invite.rb index dbdfd3a67..e8d88839c 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: invites -# -# id :integer not null, primary key -# email :string -# email_sender :string -# message :text -# created_at :datetime -# updated_at :datetime -# dossier_id :integer -# user_id :integer -# class Invite < ApplicationRecord include EmailSanitizableConcern diff --git a/app/models/logic/champ_value.rb b/app/models/logic/champ_value.rb index 462f33880..4a1c9dcc2 100644 --- a/app/models/logic/champ_value.rb +++ b/app/models/logic/champ_value.rb @@ -31,7 +31,7 @@ class Logic::ChampValue < Logic::Term targeted_champ = champ(champs) return nil if !targeted_champ.visible? - return nil if targeted_champ.blank? + return nil if targeted_champ.blank? & !targeted_champ.drop_down_other? # on dépense 22ms ici, à cause du map, mais on doit pouvoir passer par un champ type case targeted_champ.type @@ -44,6 +44,8 @@ class Logic::ChampValue < Logic::Term targeted_champ.selected when "Champs::MultipleDropDownListChamp" targeted_champ.selected_options + when "Champs::DepartementChamp" + targeted_champ.code end end diff --git a/app/models/logic/constant.rb b/app/models/logic/constant.rb index 201e37228..e1042d580 100644 --- a/app/models/logic/constant.rb +++ b/app/models/logic/constant.rb @@ -17,6 +17,8 @@ class Logic::Constant < Logic::Term I18n.t('utils.yes') when FalseClass I18n.t('utils.no') + when Champs::DropDownListChamp::OTHER + 'Autre' else @value.to_s end diff --git a/app/models/merge_log.rb b/app/models/merge_log.rb index 8ddb158bb..5e4a14ade 100644 --- a/app/models/merge_log.rb +++ b/app/models/merge_log.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: merge_logs -# -# id :bigint not null, primary key -# from_user_email :string not null -# created_at :datetime not null -# updated_at :datetime not null -# from_user_id :bigint not null -# user_id :bigint not null -# class MergeLog < ApplicationRecord belongs_to :user end diff --git a/app/models/module_api_carto.rb b/app/models/module_api_carto.rb index e2a878c69..ffc6d8dd4 100644 --- a/app/models/module_api_carto.rb +++ b/app/models/module_api_carto.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: module_api_cartos -# -# id :integer not null, primary key -# cadastre :boolean default(FALSE) -# migrated :boolean -# quartiers_prioritaires :boolean default(FALSE) -# use_api_carto :boolean default(FALSE) -# created_at :datetime -# updated_at :datetime -# procedure_id :integer -# class ModuleAPICarto < ApplicationRecord belongs_to :procedure, optional: false end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 85887c9ee..3436e11fe 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -1,69 +1,3 @@ -# == Schema Information -# -# Table name: procedures -# -# id :integer not null, primary key -# aasm_state :string default("brouillon") -# allow_expert_messaging :boolean default(TRUE), not null -# allow_expert_review :boolean default(TRUE), not null -# api_entreprise_token :string -# api_particulier_scopes :text default([]), is an Array -# api_particulier_sources :jsonb -# ask_birthday :boolean default(FALSE), not null -# auto_archive_on :date -# cadre_juridique :string -# cloned_from_library :boolean default(FALSE) -# closed_at :datetime -# declarative_with_state :string -# description :string -# description_pj :string -# description_target_audience :string -# dossiers_count_computed_at :datetime -# duree_conservation_dossiers_dans_ds :integer -# duree_conservation_etendue_par_ds :boolean default(FALSE), not null -# encrypted_api_particulier_token :string -# estimated_dossiers_count :integer -# estimated_duration_visible :boolean default(TRUE), not null -# euro_flag :boolean default(FALSE) -# experts_require_administrateur_invitation :boolean default(FALSE) -# for_individual :boolean default(FALSE) -# hidden_at :datetime -# instructeurs_self_management_enabled :boolean -# juridique_required :boolean default(TRUE) -# libelle :string -# lien_dpo :string -# lien_dpo_error :text -# lien_notice :string -# lien_notice_error :text -# lien_site_web :string -# max_duree_conservation_dossiers_dans_ds :integer default(12), not null -# migrated_champ_routage :boolean -# monavis_embed :text -# opendata :boolean default(TRUE) -# organisation :string -# path :string not null -# piece_justificative_multiple :boolean default(TRUE), not null -# procedure_expires_when_termine_enabled :boolean default(TRUE) -# published_at :datetime -# routing_criteria_name :text default("Votre ville") -# routing_enabled :boolean -# sva_svr :jsonb not null -# tags :text default([]), is an Array -# unpublished_at :datetime -# web_hook_url :string -# whitelisted_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# canonical_procedure_id :bigint -# defaut_groupe_instructeur_id :bigint -# draft_revision_id :bigint -# parent_procedure_id :bigint -# published_revision_id :bigint -# replaced_by_procedure_id :bigint -# service_id :bigint -# zone_id :bigint -# - class Procedure < ApplicationRecord include ProcedureStatsConcern include EncryptableConcern @@ -78,8 +12,7 @@ class Procedure < ApplicationRecord :durees_conservation_required, :cerfa_flag, :test_started_at, - :lien_demarche, - :migrated_champ_routage + :lien_demarche ] default_scope -> { kept } @@ -225,7 +158,9 @@ class Procedure < ApplicationRecord belongs_to :defaut_groupe_instructeur, class_name: 'GroupeInstructeur', inverse_of: false, optional: true - has_one_attached :logo + has_one_attached :logo do |attachable| + attachable.variant :email, resize_to_limit: [150, 150] + end has_one_attached :notice has_one_attached :deliberation @@ -733,12 +668,6 @@ class Procedure < ApplicationRecord routing_enabled? || instructeurs_self_management_enabled? end - def defaut_groupe_instructeur_for_new_dossier - if !routing_enabled? || feature_enabled?(:procedure_routage_api) - defaut_groupe_instructeur - end - end - def groupe_instructeurs_but_defaut groupe_instructeurs - [defaut_groupe_instructeur] end diff --git a/app/models/procedure_presentation.rb b/app/models/procedure_presentation.rb index a068d4821..385749650 100644 --- a/app/models/procedure_presentation.rb +++ b/app/models/procedure_presentation.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: procedure_presentations -# -# id :integer not null, primary key -# displayed_fields :jsonb not null -# filters :jsonb not null -# sort :jsonb not null -# created_at :datetime -# updated_at :datetime -# assign_to_id :integer -# class ProcedurePresentation < ApplicationRecord EXTRA_SORT_COLUMNS = { 'notifications' => ['notifications'], @@ -65,7 +53,7 @@ class ProcedurePresentation < ApplicationRecord field_hash('user', 'email', type: :text), field_hash('followers_instructeurs', 'email', type: :text), field_hash('groupe_instructeur', 'id', type: :enum), - field_hash('avis', 'answer', type: :text) + field_hash('avis', 'question_answer', filterable: false) ) if procedure.for_individual @@ -116,7 +104,9 @@ class ProcedurePresentation < ApplicationRecord end def filterable_fields_options - fields.map do |field| + fields.filter_map do |field| + next if field['filterable'] == false + [field['label'], field_id(field)] end end @@ -459,7 +449,7 @@ class ProcedurePresentation < ApplicationRecord end end - def field_hash(table, column, label: nil, classname: '', virtual: false, type: :text, scope: '', value_column: :value) + def field_hash(table, column, label: nil, classname: '', virtual: false, type: :text, scope: '', value_column: :value, filterable: true) { 'label' => label || I18n.t(column, scope: [:activerecord, :attributes, :procedure_presentation, :fields, table]), TABLE => table, @@ -468,7 +458,8 @@ class ProcedurePresentation < ApplicationRecord 'virtual' => virtual, 'type' => type, 'scope' => scope, - 'value_column' => value_column + 'value_column' => value_column, + 'filterable' => filterable } end diff --git a/app/models/procedure_revision.rb b/app/models/procedure_revision.rb index 20decec4c..716334e57 100644 --- a/app/models/procedure_revision.rb +++ b/app/models/procedure_revision.rb @@ -1,19 +1,5 @@ -# == Schema Information -# -# Table name: procedure_revisions -# -# id :bigint not null, primary key -# migrated_champ_routage :boolean -# published_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# attestation_template_id :bigint -# dossier_submitted_message_id :bigint -# procedure_id :bigint not null -# class ProcedureRevision < ApplicationRecord self.implicit_order_column = :created_at - self.ignored_columns += [:migrated_champ_routage] belongs_to :procedure, -> { with_discarded }, inverse_of: :revisions, optional: false belongs_to :dossier_submitted_message, inverse_of: :revisions, optional: true, dependent: :destroy @@ -164,7 +150,7 @@ class ProcedureRevision < ApplicationRecord def dossier_for_preview(user) dossier = Dossier - .create_with(groupe_instructeur: procedure.defaut_groupe_instructeur_for_new_dossier, autorisation_donnees: true) + .create_with(autorisation_donnees: true) .find_or_initialize_by(revision: self, user: user, for_procedure_preview: true, state: Dossier.states.fetch(:brouillon)) if dossier.new_record? @@ -238,7 +224,7 @@ class ProcedureRevision < ApplicationRecord end def routable_types_de_champ - types_de_champ_public.filter { |tdc| [:drop_down_list].include?(tdc.type_champ.to_sym) } + types_de_champ_public.filter { |tdc| [:drop_down_list, :departements].include?(tdc.type_champ.to_sym) } end private diff --git a/app/models/procedure_revision_type_de_champ.rb b/app/models/procedure_revision_type_de_champ.rb index 90fb598e8..b5396351e 100644 --- a/app/models/procedure_revision_type_de_champ.rb +++ b/app/models/procedure_revision_type_de_champ.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: procedure_revision_types_de_champ -# -# id :bigint not null, primary key -# position :integer not null -# created_at :datetime not null -# updated_at :datetime not null -# parent_id :bigint -# revision_id :bigint not null -# type_de_champ_id :bigint not null -# class ProcedureRevisionTypeDeChamp < ApplicationRecord belongs_to :revision, class_name: 'ProcedureRevision' belongs_to :type_de_champ diff --git a/app/models/safe_mailer.rb b/app/models/safe_mailer.rb index b4114e41a..9ccc83aef 100644 --- a/app/models/safe_mailer.rb +++ b/app/models/safe_mailer.rb @@ -1,12 +1,3 @@ -# == Schema Information -# -# Table name: safe_mailers -# -# id :bigint not null, primary key -# forced_delivery_method :string -# created_at :datetime not null -# updated_at :datetime not null -# class SafeMailer < ApplicationRecord before_create do raise if SafeMailer.count == 1 diff --git a/app/models/service.rb b/app/models/service.rb index 5bd98d3a5..ed1209663 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -1,23 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :bigint not null, primary key -# adresse :text -# email :string -# etablissement_infos :jsonb -# etablissement_lat :decimal(10, 6) -# etablissement_lng :decimal(10, 6) -# horaires :text -# nom :string not null -# organisme :string -# siret :string -# telephone :string -# type_organisme :string not null -# created_at :datetime not null -# updated_at :datetime not null -# administrateur_id :bigint -# class Service < ApplicationRecord has_many :procedures belongs_to :administrateur, optional: false diff --git a/app/models/stat.rb b/app/models/stat.rb index 77e0ace98..06dec2a55 100644 --- a/app/models/stat.rb +++ b/app/models/stat.rb @@ -1,21 +1,3 @@ -# == Schema Information -# -# Table name: stats -# -# id :bigint not null, primary key -# administrations_partenaires :bigint default(0) -# dossiers_brouillon :bigint default(0) -# dossiers_cumulative :jsonb not null -# dossiers_depose_avant_30_jours :bigint default(0) -# dossiers_deposes_entre_60_et_30_jours :bigint default(0) -# dossiers_en_construction :bigint default(0) -# dossiers_en_instruction :bigint default(0) -# dossiers_in_the_last_4_months :jsonb not null -# dossiers_not_brouillon :bigint default(0) -# dossiers_termines :bigint default(0) -# created_at :datetime not null -# updated_at :datetime not null -# class Stat < ApplicationRecord class << self def update_stats diff --git a/app/models/super_admin.rb b/app/models/super_admin.rb index 8e87e73f6..b750365a0 100644 --- a/app/models/super_admin.rb +++ b/app/models/super_admin.rb @@ -1,30 +1,3 @@ -# == Schema Information -# -# Table name: super_admins -# -# id :integer not null, primary key -# consumed_timestep :integer -# current_sign_in_at :datetime -# current_sign_in_ip :string -# email :string default(""), not null -# encrypted_otp_secret :string -# encrypted_otp_secret_iv :string -# encrypted_otp_secret_salt :string -# encrypted_password :string default(""), not null -# failed_attempts :integer default(0), not null -# last_sign_in_at :datetime -# last_sign_in_ip :string -# locked_at :datetime -# otp_required_for_login :boolean -# otp_secret :string -# remember_created_at :datetime -# reset_password_sent_at :datetime -# reset_password_token :string -# sign_in_count :integer default(0), not null -# unlock_token :string -# created_at :datetime -# updated_at :datetime -# class SuperAdmin < ApplicationRecord include PasswordComplexityConcern diff --git a/app/models/targeted_user_link.rb b/app/models/targeted_user_link.rb index 2d9d358e1..2d3d53660 100644 --- a/app/models/targeted_user_link.rb +++ b/app/models/targeted_user_link.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: targeted_user_links -# -# id :uuid not null, primary key -# target_context :string not null -# target_model_type :string not null -# created_at :datetime not null -# updated_at :datetime not null -# target_model_id :bigint not null -# user_id :bigint -# class TargetedUserLink < ApplicationRecord belongs_to :user, optional: true belongs_to :target_model, polymorphic: true, optional: false diff --git a/app/models/traitement.rb b/app/models/traitement.rb index ebf3ee0d0..6c407a154 100644 --- a/app/models/traitement.rb +++ b/app/models/traitement.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: traitements -# -# id :bigint not null, primary key -# instructeur_email :string -# motivation :string -# process_expired :boolean -# process_expired_migrated :boolean default(FALSE) -# processed_at :datetime -# state :string -# dossier_id :bigint -# class Traitement < ApplicationRecord belongs_to :dossier, optional: false diff --git a/app/models/trusted_device_token.rb b/app/models/trusted_device_token.rb index 53ba9fa9c..ddb132961 100644 --- a/app/models/trusted_device_token.rb +++ b/app/models/trusted_device_token.rb @@ -1,13 +1,3 @@ -# == Schema Information -# -# Table name: trusted_device_tokens -# -# id :bigint not null, primary key -# token :string -# created_at :datetime not null -# updated_at :datetime not null -# instructeur_id :bigint -# class TrustedDeviceToken < ApplicationRecord LOGIN_TOKEN_VALIDITY = 1.week LOGIN_TOKEN_YOUTH = 15.minutes diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 39a23f5a8..1d7be7f07 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: types_de_champ -# -# id :integer not null, primary key -# condition :jsonb -# description :text -# libelle :string -# mandatory :boolean default(FALSE) -# options :jsonb -# private :boolean default(FALSE), not null -# type_champ :string -# created_at :datetime -# updated_at :datetime -# stable_id :bigint -# class TypeDeChamp < ApplicationRecord self.ignored_columns += [:migrated_parent, :revision_id, :parent_id, :order_place] @@ -517,6 +501,14 @@ class TypeDeChamp < ApplicationRecord (drop_down_list_options - drop_down_list_disabled_options).reject(&:empty?) end + def options_with_drop_down_other + if drop_down_other? + drop_down_options + [Champs::DropDownListChamp::OTHER] + else + drop_down_options + end + end + def layer_enabled?(layer) options && options[layer] && options[layer] != '0' end diff --git a/app/models/user.rb b/app/models/user.rb index 85920d288..9aabfe35f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,35 +1,3 @@ -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# blocked_at :datetime -# blocked_reason :text -# confirmation_sent_at :datetime -# confirmation_token :string -# confirmed_at :datetime -# current_sign_in_at :datetime -# current_sign_in_ip :string -# email :string default(""), not null -# encrypted_password :string default(""), not null -# failed_attempts :integer default(0), not null -# last_sign_in_at :datetime -# last_sign_in_ip :string -# locale :string -# locked_at :datetime -# loged_in_with_france_connect :string default(NULL) -# remember_created_at :datetime -# reset_password_sent_at :datetime -# reset_password_token :string -# sign_in_count :integer default(0), not null -# siret :string -# team_account :boolean default(FALSE) -# unconfirmed_email :text -# unlock_token :string -# created_at :datetime -# updated_at :datetime -# requested_merge_into_id :bigint -# class User < ApplicationRecord include EmailSanitizableConcern include PasswordComplexityConcern diff --git a/app/models/zone.rb b/app/models/zone.rb index e4f2bce9e..cf8c806c2 100644 --- a/app/models/zone.rb +++ b/app/models/zone.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: zones -# -# id :bigint not null, primary key -# acronym :string not null -# label :string -# tchap_hs :string default([]), is an Array -# created_at :datetime not null -# updated_at :datetime not null -# class Zone < ApplicationRecord validates :acronym, presence: true, uniqueness: true has_many :labels, -> { order(designated_on: :desc) }, class_name: 'ZoneLabel', inverse_of: :zone diff --git a/app/models/zone_label.rb b/app/models/zone_label.rb index 7a3a55eae..926488b75 100644 --- a/app/models/zone_label.rb +++ b/app/models/zone_label.rb @@ -1,14 +1,3 @@ -# == 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 diff --git a/app/services/archive_uploader.rb b/app/services/archive_uploader.rb index 7da5ff246..682cd2072 100644 --- a/app/services/archive_uploader.rb +++ b/app/services/archive_uploader.rb @@ -13,6 +13,7 @@ class ArchiveUploader archive.file.detach end archive.reload + uploaded_blob.reload ActiveStorage::Attachment.create( name: 'file', record_type: 'Archive', @@ -68,7 +69,7 @@ class ArchiveUploader key: namespaced_object_key, filename: filename, content_type: 'application/zip', - metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE } + metadata: { analyzed: true, virus_scan_result: ActiveStorage::VirusScanner::SAFE } } end diff --git a/app/services/pipedrive_service.rb b/app/services/pipedrive_service.rb deleted file mode 100644 index 33b80f68e..000000000 --- a/app/services/pipedrive_service.rb +++ /dev/null @@ -1,25 +0,0 @@ -class PipedriveService - def self.accept_demande_from_person(person_id, administration_id, stage_id) - owner_id = BizDev.pipedrive_id(administration_id) - person_deals_ids = Pipedrive::DealAdapter.get_deals_ids_for_person(person_id) - person_deals_ids.each { |deal_id| Pipedrive::DealAdapter.update_deal_owner_and_stage(deal_id, owner_id, stage_id) } - Pipedrive::PersonAdapter.update_person_owner(person_id, owner_id) - end - - def self.refuse_demande_from_person(person_id, administration_id) - owner_id = BizDev.pipedrive_id(administration_id) - person_deals_ids = Pipedrive::DealAdapter.get_deals_ids_for_person(person_id) - person_deals_ids.each { |deal_id| Pipedrive::DealAdapter.refuse_deal(deal_id, owner_id) } - Pipedrive::PersonAdapter.update_person_owner(person_id, owner_id) - end - - def self.get_demandes - Pipedrive::PersonAdapter.get_demandes_from_persons_owned_by_robot - end - - def self.add_demande(email, phone, name, poste, source, organization_name, address, nb_of_procedures, nb_of_dossiers, deadline) - organization_id = Pipedrive::OrganizationAdapter.add_organization(organization_name, address) - person_id = Pipedrive::PersonAdapter.add_person(email, phone, name, organization_id, poste, source, nb_of_dossiers, deadline) - Pipedrive::DealAdapter.add_deal(organization_id, person_id, organization_name, nb_of_procedures, nb_of_dossiers, deadline) - end -end diff --git a/app/services/sva_svr_decision_date_calculator_service.rb b/app/services/sva_svr_decision_date_calculator_service.rb index 66614e524..c17fd8347 100644 --- a/app/services/sva_svr_decision_date_calculator_service.rb +++ b/app/services/sva_svr_decision_date_calculator_service.rb @@ -28,7 +28,7 @@ class SVASVRDecisionDateCalculatorService start_date = determine_start_date + 1.day correction_delay = calculate_correction_delay(start_date) - start_date + correction_delay + duration + start_date + duration + correction_delay end private diff --git a/app/views/administrateurs/groupe_instructeurs/simple_routing.html.haml b/app/views/administrateurs/groupe_instructeurs/simple_routing.html.haml index 16dfb3867..ae657c203 100644 --- a/app/views/administrateurs/groupe_instructeurs/simple_routing.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/simple_routing.html.haml @@ -24,4 +24,4 @@ %li = link_to 'Retour', options_admin_procedure_groupe_instructeurs_path(@procedure, state: :choix), class: 'fr-btn fr-btn--secondary' %li - %button.fr-btn{ disabled: true, data: { 'radio-enabled-submit-target': 'submit' } } Créer les groupes + %button.fr-btn{ disabled: true, data: { disable_with: 'Création des groupes…', 'radio-enabled-submit-target': 'submit' } } Créer les groupes diff --git a/app/views/administrateurs/procedure_administrateurs/_add_admin_form.html.haml b/app/views/administrateurs/procedure_administrateurs/_add_admin_form.html.haml index c469adade..ff8f3b5ae 100644 --- a/app/views/administrateurs/procedure_administrateurs/_add_admin_form.html.haml +++ b/app/views/administrateurs/procedure_administrateurs/_add_admin_form.html.haml @@ -1,9 +1,13 @@ = form_for procedure.administrateurs.new(user: User.new), url: { controller: 'procedure_administrateurs' }, - html: { class: 'form', id: "new_administrateur" }, + html: { id: "new_administrateur" }, data: { turbo: true, turbo_force: :server } do |f| - = f.label :email do - Ajouter un administrateur - %p.notice Renseignez l’email d’un administrateur déjà enregistré sur #{APPLICATION_NAME} pour lui permettre de modifier « #{procedure.libelle} ». - = f.email_field :email, placeholder: 'marie.dupont@exemple.fr', autofocus: true, required: true, disabled: disabled_as_super_admin - = f.submit 'Ajouter comme administrateur', class: 'button primary send', disabled: disabled_as_super_admin + .fr-input-group + = f.label :email, class: "fr-label" do + Ajouter un administrateur + %span.fr-hint-text + = "Renseignez l’email d’un administrateur déjà enregistré sur #{APPLICATION_NAME} pour lui permettre de modifier « #{procedure.libelle} ». Exemple : marie.dupont@exemple.fr" + + = f.email_field :email, required: true, class: "fr-input", autofocus: true, disabled: disabled_as_super_admin + + = f.submit 'Ajouter comme administrateur', class: 'fr-btn', disabled: disabled_as_super_admin diff --git a/app/views/administrateurs/procedure_administrateurs/index.html.haml b/app/views/administrateurs/procedure_administrateurs/index.html.haml index 26f43982a..0029eae3f 100644 --- a/app/views/administrateurs/procedure_administrateurs/index.html.haml +++ b/app/views/administrateurs/procedure_administrateurs/index.html.haml @@ -13,7 +13,6 @@ %th= 'État' %tbody#administrateurs = render(Procedure::ProcedureAdministrateurs::AdministrateurComponent.with_collection(@procedure.administrateurs.order('users.email'), procedure: @procedure)) - %tfoot - %tr - %th{ colspan: 4 } - = render 'add_admin_form', procedure: @procedure, disabled_as_super_admin: administrateur_as_manager? + + .fr-mt-4w + = render 'add_admin_form', procedure: @procedure, disabled_as_super_admin: administrateur_as_manager? diff --git a/app/views/administrateurs/procedures/_monavis.html.haml b/app/views/administrateurs/procedures/_monavis.html.haml index 2edd5a8d7..11d1f9ec7 100644 --- a/app/views/administrateurs/procedures/_monavis.html.haml +++ b/app/views/administrateurs/procedures/_monavis.html.haml @@ -11,5 +11,6 @@ %br Une fois en possession du code généré sur le site MonAvis, vous pouvez le coller dans le champ ci-dessous : -= f.label :monavis_embed, "Mon avis" -= f.text_area :monavis_embed, rows: '6', placeholder: 'Je donne mon avis', class: 'form-control' +.fr-input-group + = f.label :monavis_embed, "Mon avis", class: "fr-label" + = f.text_area :monavis_embed, rows: '6', placeholder: 'Je donne mon avis', class: 'fr-input' diff --git a/app/views/administrateurs/procedures/_procedures_list.html.haml b/app/views/administrateurs/procedures/_procedures_list.html.haml index c354dba51..31a3f6cdc 100644 --- a/app/views/administrateurs/procedures/_procedures_list.html.haml +++ b/app/views/administrateurs/procedures/_procedures_list.html.haml @@ -54,12 +54,12 @@ %span.fr-badge= procedure.dossiers.state_not_brouillon.visible_by_administration.count .text-right - %p.fr-mb-0 N° #{procedure.id} - - if procedure.close? + %p.fr-mb-0.width-max-content N° #{number_with_html_delimiter(procedure.id)} + - if procedure.close? || procedure.depubliee? %span.fr-badge.fr-badge--sm.fr-badge--warning = t('closed', scope: [:layouts, :breadcrumb]) - - elsif procedure.locked? + - elsif procedure.publiee? %span.fr-badge.fr-badge--sm.fr-badge--success = t('published', scope: [:layouts, :breadcrumb]) diff --git a/app/views/administrateurs/procedures/jeton.html.haml b/app/views/administrateurs/procedures/jeton.html.haml index 3a59e0be3..5f86e9817 100644 --- a/app/views/administrateurs/procedures/jeton.html.haml +++ b/app/views/administrateurs/procedures/jeton.html.haml @@ -9,7 +9,7 @@ .container %h1 - = form_with model: @procedure, url: url_for({ controller: 'administrateurs/procedures', action: :update_jeton }), html: { class: 'form' } do |f| + = form_with model: @procedure, url: url_for({ controller: 'administrateurs/procedures', action: :update_jeton }) do |f| %p.explication Démarches Simplifiées utilise = link_to 'API Entreprise', "https://entreprise.api.gouv.fr/" @@ -18,7 +18,7 @@ = link_to 'API Entreprise', "https://api.gouv.fr/les-api/api-entreprise/demande-acces" propre à votre démarche. - = f.label :api_entreprise_token, "Jeton" - = f.password_field :api_entreprise_token, value: @procedure.read_attribute(:api_entreprise_token), class: 'form-control' - .text-right - = f.button 'Enregistrer', class: 'button primary send' + .fr-input-group + = f.label :api_entreprise_token, "Jeton", class: 'fr-label' + = f.password_field :api_entreprise_token, value: @procedure.read_attribute(:api_entreprise_token), class: 'fr-input' + = f.button 'Enregistrer', class: 'fr-btn' diff --git a/app/views/administrateurs/procedures/monavis.html.haml b/app/views/administrateurs/procedures/monavis.html.haml index a48024209..2cbc3cce3 100644 --- a/app/views/administrateurs/procedures/monavis.html.haml +++ b/app/views/administrateurs/procedures/monavis.html.haml @@ -11,5 +11,4 @@ %h1 = form_for @procedure, url: url_for({ controller: 'administrateurs/procedures', action: :update_monavis }), html: { class: 'form', multipart: true } do |f| = render partial: 'monavis', locals: { f: f } - .text-right - = f.button 'Enregistrer', class: 'button primary send' + = f.button 'Enregistrer', class: 'fr-btn' diff --git a/app/views/administrateurs/services/_form.html.haml b/app/views/administrateurs/services/_form.html.haml index 414a291b4..62b058522 100644 --- a/app/views/administrateurs/services/_form.html.haml +++ b/app/views/administrateurs/services/_form.html.haml @@ -1,35 +1,19 @@ -= form_with model: [ :admin, service], local: true, html: { class: 'form' } do |f| += form_with model: [ :admin, service], local: true do |f| - = f.label :nom do - Nom du service - %span.mandatory * + = render Dsfr::InputComponent.new(form: f, attribute: :nom, input_type: :text_field) - %p.notice Indiquez le nom et la direction rattachée séparé par une virgule + = render Dsfr::InputComponent.new(form: f, attribute: :organisme, input_type: :text_field) - = f.text_field :nom, placeholder: 'service jeunesse et prévention, direction des affaires maritimes', required: true + .fr-input-group + = f.label :type_organisme, class: "fr-label" do + Type d’organisme - = f.label :organisme do - Organisme/s - %span.mandatory * - %p.notice Indiquez les organismes depuis l’échelon territorial jusqu’au ministère séparés par une virgule - = f.text_field :organisme, placeholder: "mairie de Mours, préfecture de l'Oise, ministère de la Culture", required: true + = f.select :type_organisme, Service.type_organismes.keys.map { |key| [ I18n.t("type_organisme.#{key}"), key] }, {}, class: 'fr-select' - = f.label :type_organisme do - Type d’organisme - %span.mandatory * - - = f.select :type_organisme, Service.type_organismes.keys.map { |key| [ I18n.t("type_organisme.#{key}"), key] }, class: 'width-33-desktop width-100-mobile' - - = f.label :siret do - Numéro SIRET - %span.mandatory * - - %p.notice - Veuillez saisir le numéro de SIRET de l’organisme dont ce service dépend. - %br - = link_to "➡ Rechercher le numéro SIRET sur « annuaire-entreprises.data.gouv.fr »", annuaire_link, target: "_blank" - - = f.text_field :siret, placeholder: "14 chiffres", required: true + = render Dsfr::InputComponent.new(form: f, attribute: :siret, input_type: :text_field, opts: { placeholder: "14 chiffres, sans espace" }) do |c| + - c.with_hint do + = "Indiquez le numéro de SIRET de l’organisme dont ce service dépend. Rechercher le SIRET sur " + = link_to("annuaire-entreprises.data.gouv.fr", annuaire_link, **external_link_attributes) = render Dsfr::CalloutComponent.new(title: "Informations de contact") do |c| - c.body do @@ -42,31 +26,10 @@ %br Ces informations de contact seront visibles par les utilisateurs de la démarche, affichées dans le menu « Aide », ainsi qu’en pied de page lors du dépôt d’un dossier. En cas d’informations invalides, #{APPLICATION_NAME} se réserve le droit de suspendre la publication de la démarche. - = f.label :email do - Adresse email - %span.mandatory * - - %p.notice - Indiquez une adresse Email valide qui permettra de recevoir et de répondre aux questions des usagers. - - = f.email_field :email, placeholder: 'contact@mon-service.fr', required: true, class: 'width-33-desktop width-100-mobile' - - = f.label :telephone do - Numéro de téléphone - %span.mandatory * - %p.notice Indiquez le numéro de téléphone du service valide le plus à même de fournir des réponses pertinentes à vos usagers - = f.telephone_field :telephone, placeholder: '04 12 24 42 37', required: true, class: 'width-33-desktop width-100-mobile' - - = f.label :horaires do - Horaires - %span.mandatory * - %p.notice Indiquez les jours ouvrables et les horaires où les usagers peuvent vous joindre - = f.text_area :horaires, placeholder: "Du lundi au vendredi de 9 h 30 à 17 h 30. Le samedi de 9 h 30 à 12 h.", required: true, class: 'width-66-desktop width-100-mobile' - - = f.label :adresse do - Adresse postale - %span.mandatory * - = f.text_area :adresse, placeholder: "20 avenue de Ségur, 75007 Paris", required: true, class: 'width-66-desktop width-100-mobile' + = render Dsfr::InputComponent.new(form: f, attribute: :email, input_type: :email_field) + = render Dsfr::InputComponent.new(form: f, attribute: :telephone, input_type: :telephone_field) + = render Dsfr::InputComponent.new(form: f, attribute: :horaires, input_type: :text_area) + = render Dsfr::InputComponent.new(form: f, attribute: :adresse, input_type: :text_area) - if procedure_id.present? = hidden_field_tag :procedure_id, procedure_id diff --git a/app/views/champs/options/remove.turbo_stream.haml b/app/views/champs/options/remove.turbo_stream.haml index b8c303ff1..679c610de 100644 --- a/app/views/champs/options/remove.turbo_stream.haml +++ b/app/views/champs/options/remove.turbo_stream.haml @@ -1,3 +1 @@ -= fields_for @champ.input_name, @champ do |form| - = turbo_stream.replace @champ.input_group_id do - = render EditableChamp::EditableChampComponent.new champ: @champ, form: += render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update } diff --git a/app/views/instructeur_mailer/send_login_token.html.haml b/app/views/instructeur_mailer/send_login_token.html.haml index 2bb0cd142..135401c5f 100644 --- a/app/views/instructeur_mailer/send_login_token.html.haml +++ b/app/views/instructeur_mailer/send_login_token.html.haml @@ -2,7 +2,7 @@ Bonjour, %p - Veuillez cliquer sur le lien suivant pour vous connecter sur le site #{APPLICATION_NAME} :  + Veuillez cliquer sur le lien sécurisé suivant pour vous connecter à #{APPLICATION_NAME} :  = link_to(sign_in_by_link_url(@instructeur_id, jeton: @login_token), sign_in_by_link_url(@instructeur_id, jeton: @login_token)) %p diff --git a/app/views/instructeurs/dossiers/update_annotations.turbo_stream.haml b/app/views/instructeurs/dossiers/update_annotations.turbo_stream.haml index 83ca04a5d..679c610de 100644 --- a/app/views/instructeurs/dossiers/update_annotations.turbo_stream.haml +++ b/app/views/instructeurs/dossiers/update_annotations.turbo_stream.haml @@ -1,8 +1 @@ -- if @to_show.present? - = turbo_stream.show_all(@to_show) -- if @to_hide.present? - = turbo_stream.hide_all(@to_hide) -- @to_update.each do |champ| - = fields_for champ.input_name, champ do |form| - = turbo_stream.replace champ.input_group_id do - = render EditableChamp::EditableChampComponent.new champ:, form: += render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update } diff --git a/app/views/instructeurs/procedures/email_usagers.html.haml b/app/views/instructeurs/procedures/email_usagers.html.haml index 115a47a33..61af93444 100644 --- a/app/views/instructeurs/procedures/email_usagers.html.haml +++ b/app/views/instructeurs/procedures/email_usagers.html.haml @@ -3,30 +3,35 @@ = render partial: 'administrateurs/breadcrumbs', locals: { steps: [[@procedure.libelle.truncate_words(10), instructeur_procedure_path(@procedure)], [t('.contact_users')]] } -.messagerie.container - - if @email_usagers_dossiers.present? - %p.notice.mb-2.mt-4 - = t('.notice', dossiers_count: pluralize(@dossiers_count, 'personne'), groupe_instructeurs: @groupe_instructeurs.join(', ')) +.messagerie.fr-container + %h1 Contacter les usagers + %p.fr-highlight + = t('.hint', count: @dossiers_without_groupe_count).html_safe - = render partial: 'shared/dossiers/messages/form', locals: { commentaire: @commentaire, form_url: create_multiple_commentaire_instructeur_procedure_path(@procedure), disable_piece_jointe: true } + - if @dossiers_without_groupe_count.positive? + = form_for(@bulk_message, url: create_multiple_commentaire_instructeur_procedure_path, html: { data: { controller: 'persisted-form', persisted_form_key_value: dom_id(@procedure, :bulk_message) } }) do |f| - - if @bulk_messages.present? - %section.list-avis.mt-8 - %h1.tab-title - Messages envoyés précédemment - %span.fr-badge= @bulk_messages.count + %p.mandatory-explanation= t('asterisk_html', scope: [:utils]) - %ul - - @bulk_messages.each do |message| - %li.one-avis.flex.align-start - .width-100 - %h2.claimant - %span.email= message.instructeur.email - %span.date message envoyé à #{@dossiers_count} usagers le #{message.sent_at.strftime('%d/%m/%y à %H:%M')} - %p= message.body - .answer.flex.align-start - - if message.piece_jointe.present? - = render Attachment::ShowComponent.new(attachment: message.piece_jointe.attachment) + = render Dsfr::InputComponent.new(form: f, attribute: :body, input_type: :text_area, opts: { rows: 5, placeholder: t('views.shared.dossiers.messages.form.write_message_placeholder'), title: t('views.shared.dossiers.messages.form.write_message_placeholder'), class: 'fr-input message-textarea'}) + + .fr-mt-3w + = f.submit t('views.shared.dossiers.messages.form.send_message'), class: 'fr-btn', data: { disable: true } - else .page-title.center - %h2 Il n’y a aucun dossier en brouillon dans vos groupes d’instructeurs + %h2 Il n’y a aucun dossier en brouillon + + - if @bulk_messages.present? + %section.list-avis.mt-8 + %h1.tab-title + Messages envoyés précédemment + %span.fr-badge= @bulk_messages.count + + %ul + - @bulk_messages.each do |message| + %li.one-avis.flex.align-start + .width-100 + %h2.claimant + %span.email= message.instructeur.email + %span.date message envoyé à #{@dossiers_count} usagers le #{message.sent_at.strftime('%d/%m/%y à %H:%M')} + %p= message.body diff --git a/app/views/invites/_form.html.haml b/app/views/invites/_form.html.haml index 7d0ce75b9..8dded1989 100644 --- a/app/views/invites/_form.html.haml +++ b/app/views/invites/_form.html.haml @@ -1,13 +1,13 @@ -#invites-form +#invites-form.fr-p-2w - if invites.present? #invite-list{ morphing ? { tabindex: "-1" } : {} } - %h4= t('views.invites.form.invite_to_participate') + %h4.fr-h6= t('views.invites.form.invite_to_participate') %ul - invites.each do |invite| %li = invite.email %small{ 'data-turbo': 'true' } - = link_to t('views.invites.form.withdraw_permission'), invite_path(invite), data: { turbo_method: :delete, turbo_confirm: t('views.invites.form.want_to_withdraw_permission') } + = link_to t('views.invites.form.withdraw_permission'), invite_path(invite), data: { turbo_method: :delete, turbo_confirm: t('views.invites.form.want_to_withdraw_permission') }, class: "fr-btn fr-btn--sm fr-btn--tertiary-no-outline" %p= t('views.invites.form.edit_dossier') - if dossier.brouillon? @@ -17,15 +17,15 @@ %p= t('views.invites.form.invite_to_edit_line1') %p= t('views.invites.form.invite_to_edit_line2') - = form_tag dossier_invites_path(dossier), data: { turbo: true, turbo_force: :server }, method: :post, class: 'form' do - .row - .col - %span - = label_tag :invite_email, t('views.invites.form.email') - = email_field_tag :invite_email, '', class: 'small', placeholder: t('views.invites.form.email'), required: true - .col - %span - = label_tag :invite_message, t('views.invites.form.invite_message') - = text_area_tag :invite_message, '', class: 'small', placeholder: t('views.invites.form.invite_message') - .col - = submit_tag t('views.invites.form.send_invitation'), class: 'fr-btn fr-btn--secondary' + = form_tag dossier_invites_path(dossier), data: { turbo: true, turbo_force: :server }, method: :post do + .fr-input-group + = label_tag :invite_email, class: "fr-label" do + = t('views.invites.form.email') + %span.fr-hint-text= t('views.invites.form.email_hint') + = email_field_tag :invite_email, '', required: true, class: "fr-input" + + .fr-input-group + = label_tag :invite_message, t('views.invites.form.invite_message'), class: "fr-label" + = text_area_tag :invite_message, '', class: "fr-input" + + = submit_tag t('views.invites.form.send_invitation'), class: 'fr-btn fr-btn--secondary' diff --git a/app/views/manager/application/_user_meta.html.erb b/app/views/manager/application/_user_meta.html.erb index 46185a0a4..4b76f3ff7 100644 --- a/app/views/manager/application/_user_meta.html.erb +++ b/app/views/manager/application/_user_meta.html.erb @@ -11,7 +11,8 @@ Usager
- <%= link_to('Voir son compte utilisateur', manager_user_path(user)) %> + <% style = "background-color: red;color: white;" if user.blocked_at %> + <%= link_to('Voir son compte utilisateur', manager_user_path(user), style: style) %>
diff --git a/app/views/manager/demandes/index.html.erb b/app/views/manager/demandes/index.html.erb deleted file mode 100644 index 6d4fb534a..000000000 --- a/app/views/manager/demandes/index.html.erb +++ /dev/null @@ -1,63 +0,0 @@ -<% content_for(:title) do %> - <%= display_resource_name('Demandes') %> -<% end %> - - -

-Plus de 1000 dossiers et "le plus vite possible" 👉 c'est un VIP ❤️. Appelez-le 📞 pour répondre à ses questions. -

-<% if @pending_demandes.present? %> -
- - - <% keys = @pending_demandes.first.keys %> - - <% keys.each do |key| %> - - <% end %> - - - - <% @pending_demandes.each do |demande| %> - - <% keys.each do |key| %> - - <% end %> - - - - <% end %> - -
- <%= key %> - -
- <%= demande[key] %> - - <%= form_tag(manager_demandes_create_administrateur_path) do -%> - <%= select_tag "stage_id", - options_for_select({ - "suspect" => Pipedrive::DealAdapter::PIPEDRIVE_SUSPECTS_COMPTE_CREE_STAGE_ID - - }), - style: 'margin-bottom: 20px; width: inherit;' %> - - <%= hidden_field_tag 'email', demande[:email] %> - <%= hidden_field_tag 'person_id', demande[:person_id] %> - - <%= submit_tag 'Créer' %> - <% end -%> - - <%= button_to('Refuser', - manager_demandes_refuse_administrateur_path, - params: { person_id: demande[:person_id], email: demande[:email] }, - style: 'background-color: #FFFFFF; color: #293f54; border: 1px solid #dfe0e1') %> -
-
-<% else %> -

Aucune demande

-<% end %> diff --git a/app/views/manager/users/show.html.erb b/app/views/manager/users/show.html.erb index 24b793aa9..03e68bc26 100644 --- a/app/views/manager/users/show.html.erb +++ b/app/views/manager/users/show.html.erb @@ -20,8 +20,9 @@ as well as a link to its edit page. <% user = page.resource %>