Merge branch 'main' into poc-self_hosted_runners
This commit is contained in:
commit
4214c31f08
229 changed files with 1086 additions and 2782 deletions
3
Gemfile
3
Gemfile
|
@ -59,6 +59,7 @@ gem 'lograge'
|
||||||
gem 'logstash-event'
|
gem 'logstash-event'
|
||||||
gem 'mailjet', require: false
|
gem 'mailjet', require: false
|
||||||
gem 'matrix' # needed by prawn and not default in ruby 3.1
|
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-imap', require: false # See https://github.com/mikel/mail/pull/1439
|
||||||
gem 'net-pop', require: false # same
|
gem 'net-pop', require: false # same
|
||||||
gem 'net-smtp', require: false # same
|
gem 'net-smtp', require: false # same
|
||||||
|
@ -105,6 +106,7 @@ group :test do
|
||||||
gem 'rack_session_access'
|
gem 'rack_session_access'
|
||||||
gem 'rails-controller-testing'
|
gem 'rails-controller-testing'
|
||||||
gem 'rspec_junit_formatter'
|
gem 'rspec_junit_formatter'
|
||||||
|
gem 'rspec-retry'
|
||||||
gem 'selenium-devtools'
|
gem 'selenium-devtools'
|
||||||
gem 'selenium-webdriver'
|
gem 'selenium-webdriver'
|
||||||
gem 'shoulda-matchers', require: false
|
gem 'shoulda-matchers', require: false
|
||||||
|
@ -114,7 +116,6 @@ group :test do
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'annotate'
|
|
||||||
gem 'brakeman', require: false
|
gem 'brakeman', require: false
|
||||||
gem 'haml-lint'
|
gem 'haml-lint'
|
||||||
gem 'letter_opener_web'
|
gem 'letter_opener_web'
|
||||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -101,9 +101,6 @@ GEM
|
||||||
aes_key_wrap (1.1.0)
|
aes_key_wrap (1.1.0)
|
||||||
after_party (1.11.2)
|
after_party (1.11.2)
|
||||||
anchored (1.1.0)
|
anchored (1.1.0)
|
||||||
annotate (3.2.0)
|
|
||||||
activerecord (>= 3.2, < 8.0)
|
|
||||||
rake (>= 10.4, < 14.0)
|
|
||||||
ast (2.4.2)
|
ast (2.4.2)
|
||||||
attr_required (1.0.1)
|
attr_required (1.0.1)
|
||||||
axe-core-api (4.2.1)
|
axe-core-api (4.2.1)
|
||||||
|
@ -490,7 +487,7 @@ GEM
|
||||||
pry-rails (0.3.9)
|
pry-rails (0.3.9)
|
||||||
pry (>= 0.10.4)
|
pry (>= 0.10.4)
|
||||||
public_suffix (5.0.1)
|
public_suffix (5.0.1)
|
||||||
puma (6.1.1)
|
puma (6.3.1)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
pundit (2.2.0)
|
pundit (2.2.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
|
@ -604,6 +601,8 @@ GEM
|
||||||
rspec-expectations (~> 3.11)
|
rspec-expectations (~> 3.11)
|
||||||
rspec-mocks (~> 3.11)
|
rspec-mocks (~> 3.11)
|
||||||
rspec-support (~> 3.11)
|
rspec-support (~> 3.11)
|
||||||
|
rspec-retry (0.6.2)
|
||||||
|
rspec-core (> 3.3)
|
||||||
rspec-support (3.12.0)
|
rspec-support (3.12.0)
|
||||||
rspec_junit_formatter (0.4.1)
|
rspec_junit_formatter (0.4.1)
|
||||||
rspec-core (>= 2, < 4, != 2.12.0)
|
rspec-core (>= 2, < 4, != 2.12.0)
|
||||||
|
@ -813,7 +812,6 @@ DEPENDENCIES
|
||||||
administrate-field-enum
|
administrate-field-enum
|
||||||
after_party
|
after_party
|
||||||
anchored
|
anchored
|
||||||
annotate
|
|
||||||
axe-core-rspec
|
axe-core-rspec
|
||||||
bcrypt
|
bcrypt
|
||||||
bootsnap (>= 1.4.4)
|
bootsnap (>= 1.4.4)
|
||||||
|
@ -872,6 +870,7 @@ DEPENDENCIES
|
||||||
matrix
|
matrix
|
||||||
memory_profiler
|
memory_profiler
|
||||||
mina
|
mina
|
||||||
|
mini_magick
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
|
@ -898,6 +897,7 @@ DEPENDENCIES
|
||||||
rexml
|
rexml
|
||||||
rqrcode
|
rqrcode
|
||||||
rspec-rails
|
rspec-rails
|
||||||
|
rspec-retry
|
||||||
rspec_junit_formatter
|
rspec_junit_formatter
|
||||||
rubocop
|
rubocop
|
||||||
rubocop-performance
|
rubocop-performance
|
||||||
|
|
|
@ -102,6 +102,10 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.width-max-content {
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
// sizing
|
// sizing
|
||||||
.width-100 {
|
.width-100 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// overwrite DSFR style for SimpleFormatComponent, some user use markdown with
|
// overwrite DSFR style for SimpleFormatComponent, some user use markdown with
|
||||||
// ordered list having paragraph between list item
|
// ordered list having paragraph between list item
|
||||||
.fr-ol-content--override {
|
ol.fr-ol-content--override {
|
||||||
list-style-type: decimal;
|
list-style-type: decimal;
|
||||||
|
|
||||||
li::marker {
|
li::marker {
|
||||||
|
|
|
@ -1,34 +1,6 @@
|
||||||
@import "constants";
|
|
||||||
|
|
||||||
#invites-form {
|
#invites-form {
|
||||||
padding: $default-padding;
|
@media (min-width: 48em) {
|
||||||
text-align: left;
|
min-width: 400px;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
module Dsfr
|
module Dsfr
|
||||||
module InputErrorable
|
module InputErrorable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
||||||
delegate :object, to: :@form
|
delegate :object, to: :@form
|
||||||
delegate :errors, to: :object
|
delegate :errors, to: :object
|
||||||
|
|
||||||
|
renders_one :hint
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# lookup for edge case from `form.rich_text_area`
|
# lookup for edge case from `form.rich_text_area`
|
||||||
|
@ -89,6 +92,10 @@ module Dsfr
|
||||||
end
|
end
|
||||||
|
|
||||||
def hint
|
def hint
|
||||||
|
get_slot(:hint).presence || default_hint
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_hint
|
||||||
I18n.t("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}")
|
I18n.t("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -101,6 +108,8 @@ module Dsfr
|
||||||
end
|
end
|
||||||
|
|
||||||
def hint?
|
def hint?
|
||||||
|
return true if get_slot(:hint).present?
|
||||||
|
|
||||||
I18n.exists?("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}")
|
I18n.exists?("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
class Instructeurs::ActivateAccountFormComponent < ApplicationComponent
|
||||||
|
attr_reader :user
|
||||||
|
def initialize(user:)
|
||||||
|
@user = user
|
||||||
|
end
|
||||||
|
end
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
|
@ -4,7 +4,7 @@ fr:
|
||||||
Le routage permet d’acheminer les dossiers vers différents groupes d’instructeurs.
|
Le routage permet d’acheminer les dossiers vers différents groupes d’instructeurs.
|
||||||
routing_configuration_notice_2_html: |
|
routing_configuration_notice_2_html: |
|
||||||
<p>Pour le configurer, votre formulaire doit comporter
|
<p>Pour le configurer, votre formulaire doit comporter
|
||||||
au moins un champ « choix simple ».</p>
|
au moins un champ de type « choix simple » ou « départements ».</p>
|
||||||
<p>Ajoutez ce champ dans la page <a href="%{path}">« Configuration des champs »</a>.</p>
|
<p>Ajoutez ce champ dans la page <a href="%{path}">« Configuration des champs »</a>.</p>
|
||||||
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_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: |
|
delete_confirmation: |
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
class: 'fr-btn',
|
class: 'fr-btn',
|
||||||
method: :delete,
|
method: :delete,
|
||||||
title: t('.delete_title', defaut_label: @procedure.defaut_groupe_instructeur.label),
|
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'
|
- elsif @state == 'choix'
|
||||||
= form_for :choice,
|
= form_for :choice,
|
||||||
|
|
|
@ -58,8 +58,18 @@ class Procedure::OneGroupeManagementComponent < ApplicationComponent
|
||||||
|
|
||||||
def available_values_for_select(targeted_champ)
|
def available_values_for_select(targeted_champ)
|
||||||
return [] if targeted_champ.is_a?(Logic::Empty)
|
return [] if targeted_champ.is_a?(Logic::Empty)
|
||||||
|
|
||||||
|
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
|
targeted_champ
|
||||||
.options(@revision.types_de_champ_public)
|
.options(@revision.types_de_champ_public)
|
||||||
.map { |tdc| [tdc.first, constant(tdc.first).to_json] }
|
.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
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@ fr:
|
||||||
other: "%{count} dossiers en cours de traitement portent ce champ. Les <strong>données</strong> associées avec ce champ seront <strong>supprimées</strong>."
|
other: "%{count} dossiers en cours de traitement portent ce champ. Les <strong>données</strong> associées avec ce champ seront <strong>supprimées</strong>."
|
||||||
add_option: "ajoutés : %{items}"
|
add_option: "ajoutés : %{items}"
|
||||||
remove_option: "supprimé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:
|
public:
|
||||||
add: Le champ « %{label} » a été ajouté.
|
add: Le champ « %{label} » a été ajouté.
|
||||||
add_mandatory: Le champ obligatoire « %{label} » a été ajouté.
|
add_mandatory: Le champ obligatoire « %{label} » a été ajouté.
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
- if !total_dossiers.zero? && !change.can_rebase?
|
- if !total_dossiers.zero? && !change.can_rebase?
|
||||||
.fr-alert.fr-alert--warning.fr-mt-1v
|
.fr-alert.fr-alert--warning.fr-mt-1v
|
||||||
%p= t('.breaking_change', count: total_dossiers)
|
%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
|
.fr-alert.fr-alert--warning.fr-mt-1v
|
||||||
= t(".#{prefix}.update_drop_down_options_alert", label: change.label)
|
= t(".#{prefix}.update_drop_down_options_alert", label: change.label)
|
||||||
- when :drop_down_other
|
- when :drop_down_other
|
||||||
|
@ -148,3 +148,7 @@
|
||||||
- if @private_move_changes.present?
|
- if @private_move_changes.present?
|
||||||
- list.with_item do
|
- list.with_item do
|
||||||
= t(".private.move", count: @private_move_changes.size)
|
= 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")
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
= form_tag(search_admin_procedures_path, data: { turbo: true }, method: :post, class: 'form') do
|
= form_tag(search_admin_procedures_path, data: { turbo: true }, method: :post) do
|
||||||
= label_tag :query, 'Rechercher une procédure'
|
.fr-input-group
|
||||||
|
= label_tag :query, class: "fr-label" do
|
||||||
|
Rechercher une démarche
|
||||||
|
%span.fr-hint-text Saisissez au moins 3 lettres
|
||||||
|
|
||||||
.notice
|
= text_field_tag :query, params[:query], required: true, placeholder: 'politique de la ville', minlength: "3", class: "fr-input"
|
||||||
%p Entrez au minimum 3 lettres
|
|
||||||
|
|
||||||
|
|
||||||
= text_field_tag :query, params[:query], required: true, placeholder: 'politique de la ville', minlength: "3"
|
|
||||||
|
|
||||||
= submit_tag 'Rechercher', class: 'fr-btn'
|
= submit_tag 'Rechercher', class: 'fr-btn'
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,34 @@ module Administrateurs
|
||||||
|
|
||||||
tdc = @procedure.active_revision.routable_types_de_champ.find { |tdc| tdc.stable_id == stable_id }
|
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
|
||||||
|
|
||||||
|
when TypeDeChamp.type_champs.fetch(:drop_down_list)
|
||||||
|
tdc_options = tdc.drop_down_options.reject(&:empty?)
|
||||||
tdc_options.each do |option_label|
|
tdc_options.each do |option_label|
|
||||||
gi = @procedure.groupe_instructeurs.find_by({ label: option_label }) || @procedure.groupe_instructeurs
|
routing_rule = ds_eq(champ_value(stable_id), constant(option_label))
|
||||||
.create({ label: option_label, instructeurs: [current_administrateur.instructeur] })
|
@procedure
|
||||||
gi.update(routing_rule: ds_eq(champ_value(stable_id), constant(gi.label)))
|
.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
|
end
|
||||||
|
|
||||||
@procedure.toggle_routing
|
@procedure.toggle_routing
|
||||||
|
|
|
@ -4,7 +4,6 @@ class API::Public::V1::DossiersController < API::Public::V1::BaseController
|
||||||
def create
|
def create
|
||||||
dossier = Dossier.new(
|
dossier = Dossier.new(
|
||||||
revision: @procedure.active_revision,
|
revision: @procedure.active_revision,
|
||||||
groupe_instructeur: @procedure.defaut_groupe_instructeur_for_new_dossier,
|
|
||||||
state: Dossier.states.fetch(:brouillon),
|
state: Dossier.states.fetch(:brouillon),
|
||||||
prefilled: true
|
prefilled: true
|
||||||
)
|
)
|
||||||
|
|
|
@ -39,7 +39,9 @@ class API::V2::BaseController < ApplicationController
|
||||||
|
|
||||||
def api_token
|
def api_token
|
||||||
if @api_token.nil?
|
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
|
end
|
||||||
@api_token
|
@api_token
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,7 @@ class APIController < ApplicationController
|
||||||
def find_administrateur_for_token(procedure)
|
def find_administrateur_for_token(procedure)
|
||||||
api_token = APIToken.find_and_verify(authorization_bearer_token, procedure.administrateurs)
|
api_token = APIToken.find_and_verify(authorization_bearer_token, procedure.administrateurs)
|
||||||
if api_token.present? && api_token.context.fetch(:procedure_ids).include?(procedure.id)
|
if api_token.present? && api_token.context.fetch(:procedure_ids).include?(procedure.id)
|
||||||
|
api_token.touch(:last_v1_authenticated_at)
|
||||||
api_token.administrateur
|
api_token.administrateur
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
class Champs::OptionsController < ApplicationController
|
class Champs::OptionsController < ApplicationController
|
||||||
|
include TurboChampsConcern
|
||||||
|
|
||||||
before_action :authenticate_logged_user!
|
before_action :authenticate_logged_user!
|
||||||
|
|
||||||
def remove
|
def remove
|
||||||
@champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
||||||
@champ.remove_option([params[:option]].compact)
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -85,7 +85,8 @@ module Instructeurs
|
||||||
end
|
end
|
||||||
|
|
||||||
def personnes_impliquees
|
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_followers = dossier.previous_followers_instructeurs - dossier.followers_instructeurs
|
||||||
@previous_following_instructeurs_emails = previous_followers.map(&:email)
|
@previous_following_instructeurs_emails = previous_followers.map(&:email)
|
||||||
@avis_emails = dossier.experts.map(&:email)
|
@avis_emails = dossier.experts.map(&:email)
|
||||||
|
|
|
@ -224,19 +224,18 @@ module Instructeurs
|
||||||
|
|
||||||
def email_usagers
|
def email_usagers
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
@commentaire = Commentaire.new
|
@bulk_messages = BulkMessage.includes(:groupe_instructeurs).where(groupe_instructeurs: { procedure: procedure })
|
||||||
@email_usagers_dossiers = email_usagers_dossiers
|
@bulk_message = current_instructeur.bulk_messages.build
|
||||||
@dossiers_count = @email_usagers_dossiers.count
|
@dossiers_without_groupe_count = procedure.dossiers.state_brouillon.for_groupe_instructeur(nil).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 })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_multiple_commentaire
|
def create_multiple_commentaire
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
errors = []
|
errors = []
|
||||||
|
bulk_message = current_instructeur.bulk_messages.build(bulk_message_params)
|
||||||
email_usagers_dossiers.each do |dossier|
|
dossiers = procedure.dossiers.state_brouillon.for_groupe_instructeur(nil)
|
||||||
commentaire = CommentaireService.create(current_instructeur, dossier, commentaire_params)
|
dossiers.each do |dossier|
|
||||||
|
commentaire = CommentaireService.create(current_instructeur, dossier, bulk_message_params.except(:targets))
|
||||||
if commentaire.errors.empty?
|
if commentaire.errors.empty?
|
||||||
commentaire.dossier.update!(last_commentaire_updated_at: Time.zone.now)
|
commentaire.dossier.update!(last_commentaire_updated_at: Time.zone.now)
|
||||||
else
|
else
|
||||||
|
@ -244,8 +243,15 @@ module Instructeurs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
valid_dossiers_count = email_usagers_dossiers.count - errors.count
|
valid_dossiers_count = dossiers.count - errors.count
|
||||||
create_bulk_message_mail(valid_dossiers_count, Dossier.states.fetch(:brouillon))
|
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?
|
if errors.empty?
|
||||||
flash[:notice] = "Tous les messages ont été envoyés avec succès"
|
flash[:notice] = "Tous les messages ont été envoyés avec succès"
|
||||||
|
@ -262,18 +268,6 @@ module Instructeurs
|
||||||
|
|
||||||
private
|
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
|
def assign_to_params
|
||||||
params.require(:assign_to)
|
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)
|
.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, [])
|
@current_filters ||= procedure_presentation.filters.fetch(statut, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def email_usagers_dossiers
|
def bulk_message_params
|
||||||
procedure.dossiers.state_brouillon.where(groupe_instructeur: current_instructeur.groupe_instructeur_ids).includes(:groupe_instructeur)
|
params.require(:bulk_message).permit(:body)
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
|
17
app/controllers/procedures_controller.rb
Normal file
17
app/controllers/procedures_controller.rb
Normal file
|
@ -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
|
|
@ -20,6 +20,8 @@ module Users
|
||||||
check_prefilled_dossier_ownership if @prefilled_dossier
|
check_prefilled_dossier_ownership if @prefilled_dossier
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@usual_traitement_time = @procedure.stats_usual_traitement_time
|
||||||
|
|
||||||
render 'commencer/show'
|
render 'commencer/show'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -94,7 +96,6 @@ module Users
|
||||||
def build_prefilled_dossier
|
def build_prefilled_dossier
|
||||||
@prefilled_dossier = Dossier.new(
|
@prefilled_dossier = Dossier.new(
|
||||||
revision: @revision,
|
revision: @revision,
|
||||||
groupe_instructeur: @procedure.defaut_groupe_instructeur_for_new_dossier,
|
|
||||||
state: Dossier.states.fetch(:brouillon),
|
state: Dossier.states.fetch(:brouillon),
|
||||||
prefilled: true
|
prefilled: true
|
||||||
)
|
)
|
||||||
|
|
|
@ -375,7 +375,6 @@ module Users
|
||||||
|
|
||||||
dossier = Dossier.new(
|
dossier = Dossier.new(
|
||||||
revision: params[:brouillon] ? procedure.draft_revision : procedure.active_revision,
|
revision: params[:brouillon] ? procedure.draft_revision : procedure.active_revision,
|
||||||
groupe_instructeur: procedure.defaut_groupe_instructeur_for_new_dossier,
|
|
||||||
user: current_user,
|
user: current_user,
|
||||||
state: Dossier.states.fetch(:brouillon)
|
state: Dossier.states.fetch(:brouillon)
|
||||||
)
|
)
|
||||||
|
@ -542,6 +541,7 @@ module Users
|
||||||
|
|
||||||
def update_dossier_and_compute_errors
|
def update_dossier_and_compute_errors
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
@dossier.assign_attributes(champs_public_params)
|
@dossier.assign_attributes(champs_public_params)
|
||||||
if @dossier.champs_public_all.any?(&:changed_for_autosave?)
|
if @dossier.champs_public_all.any?(&:changed_for_autosave?)
|
||||||
@dossier.last_champ_updated_at = Time.zone.now
|
@dossier.last_champ_updated_at = Time.zone.now
|
||||||
|
@ -559,7 +559,6 @@ module Users
|
||||||
@dossier.valid?(**submit_validation_options)
|
@dossier.valid?(**submit_validation_options)
|
||||||
errors += format_errors(errors: @dossier.errors)
|
errors += format_errors(errors: @dossier.errors)
|
||||||
errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs)
|
errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs)
|
||||||
|
|
||||||
errors
|
errors
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Users::SessionsController < Devise::SessionsController
|
||||||
layout 'login', only: [:new, :create]
|
layout 'login', only: [:new, :create]
|
||||||
|
|
||||||
before_action :restore_procedure_context, 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
|
# POST /resource/sign_in
|
||||||
def create
|
def create
|
||||||
user = User.find_by(email: params[:user][:email])
|
user = User.find_by(email: params[:user][:email])
|
||||||
|
@ -18,6 +18,13 @@ class Users::SessionsController < Devise::SessionsController
|
||||||
super
|
super
|
||||||
end
|
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
|
def link_sent
|
||||||
if Devise.email_regexp.match?(params[:email])
|
if Devise.email_regexp.match?(params[:email])
|
||||||
@email = params[:email]
|
@email = params[:email]
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
require "administrate/base_dashboard"
|
|
||||||
|
|
||||||
class DemandeDashboard < Administrate::BaseDashboard
|
|
||||||
end
|
|
|
@ -13,6 +13,8 @@ class UserDashboard < Administrate::BaseDashboard
|
||||||
confirmed?: Field::Boolean,
|
confirmed?: Field::Boolean,
|
||||||
created_at: Field::DateTime,
|
created_at: Field::DateTime,
|
||||||
updated_at: Field::DateTime,
|
updated_at: Field::DateTime,
|
||||||
|
blocked_at: Field::DateTime,
|
||||||
|
blocked_reason: Field::String,
|
||||||
current_sign_in_at: Field::DateTime,
|
current_sign_in_at: Field::DateTime,
|
||||||
dossiers: Field::HasMany
|
dossiers: Field::HasMany
|
||||||
}.freeze
|
}.freeze
|
||||||
|
@ -36,7 +38,9 @@ class UserDashboard < Administrate::BaseDashboard
|
||||||
:email,
|
:email,
|
||||||
:confirmed?,
|
:confirmed?,
|
||||||
:current_sign_in_at,
|
:current_sign_in_at,
|
||||||
:created_at
|
:created_at,
|
||||||
|
:blocked_at,
|
||||||
|
:blocked_reason
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
# FORM_ATTRIBUTES
|
# FORM_ATTRIBUTES
|
||||||
|
|
|
@ -59,6 +59,7 @@ class API::V2::Context < GraphQL::Query::Context
|
||||||
{
|
{
|
||||||
graphql_query: query.query_string,
|
graphql_query: query.query_string,
|
||||||
graphql_variables: query.provided_variables&.to_json,
|
graphql_variables: query.provided_variables&.to_json,
|
||||||
|
graphql_mutation: mutation?,
|
||||||
graphql_null_error: errors.any? { _1.is_a? GraphQL::InvalidNullError }.presence,
|
graphql_null_error: errors.any? { _1.is_a? GraphQL::InvalidNullError }.presence,
|
||||||
graphql_timeout_error: errors.any? { _1.is_a? GraphQL::Schema::Timeout::TimeoutError }.presence
|
graphql_timeout_error: errors.any? { _1.is_a? GraphQL::Schema::Timeout::TimeoutError }.presence
|
||||||
}.compact
|
}.compact
|
||||||
|
@ -66,6 +67,12 @@ class API::V2::Context < GraphQL::Query::Context
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def mutation?
|
||||||
|
query.lookahead.selections.any? { _1.field.type.respond_to?(:mutation) }.presence
|
||||||
|
rescue
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def compute_demarche_authorization(demarche)
|
def compute_demarche_authorization(demarche)
|
||||||
# procedure_ids and token are passed from graphql controller
|
# procedure_ids and token are passed from graphql controller
|
||||||
if self[:procedure_ids].present?
|
if self[:procedure_ids].present?
|
||||||
|
@ -73,6 +80,7 @@ class API::V2::Context < GraphQL::Query::Context
|
||||||
elsif self[:token].present?
|
elsif self[:token].present?
|
||||||
token = APIToken.find_and_verify(self[:token], demarche.administrateurs)
|
token = APIToken.find_and_verify(self[:token], demarche.administrateurs)
|
||||||
if token.present?
|
if token.present?
|
||||||
|
token.touch(:last_v2_authenticated_at)
|
||||||
Current.user = token.administrateur.user
|
Current.user = token.administrateur.user
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
|
|
|
@ -138,7 +138,7 @@ class API::V2::Schema < GraphQL::Schema
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
use Timeout, max_seconds: 10
|
use Timeout, max_seconds: 30
|
||||||
use GraphQL::Batch
|
use GraphQL::Batch
|
||||||
use GraphQL::Backtrace
|
use GraphQL::Backtrace
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ class API::V2::StoredQuery
|
||||||
$includeInstructeurs: Boolean = true
|
$includeInstructeurs: Boolean = true
|
||||||
$includeAvis: Boolean = false
|
$includeAvis: Boolean = false
|
||||||
$includeMessages: Boolean = false
|
$includeMessages: Boolean = false
|
||||||
|
$includeCorrections: Boolean = false
|
||||||
$includeGeometry: Boolean = false
|
$includeGeometry: Boolean = false
|
||||||
) {
|
) {
|
||||||
demarche(number: $demarcheNumber) {
|
demarche(number: $demarcheNumber) {
|
||||||
|
@ -135,6 +136,7 @@ class API::V2::StoredQuery
|
||||||
$includeInstructeurs: Boolean = true
|
$includeInstructeurs: Boolean = true
|
||||||
$includeAvis: Boolean = false
|
$includeAvis: Boolean = false
|
||||||
$includeMessages: Boolean = false
|
$includeMessages: Boolean = false
|
||||||
|
$includeCorrections: Boolean = false
|
||||||
$includeGeometry: Boolean = false
|
$includeGeometry: Boolean = false
|
||||||
) {
|
) {
|
||||||
groupeInstructeur(number: $groupeInstructeurNumber) {
|
groupeInstructeur(number: $groupeInstructeurNumber) {
|
||||||
|
@ -201,6 +203,7 @@ class API::V2::StoredQuery
|
||||||
$includeInstructeurs: Boolean = true
|
$includeInstructeurs: Boolean = true
|
||||||
$includeAvis: Boolean = false
|
$includeAvis: Boolean = false
|
||||||
$includeMessages: Boolean = false
|
$includeMessages: Boolean = false
|
||||||
|
$includeCorrections: Boolean = false
|
||||||
$includeGeometry: Boolean = false
|
$includeGeometry: Boolean = false
|
||||||
) {
|
) {
|
||||||
dossier(number: $dossierNumber) {
|
dossier(number: $dossierNumber) {
|
||||||
|
@ -239,6 +242,7 @@ class API::V2::StoredQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment DossierFragment on Dossier {
|
fragment DossierFragment on Dossier {
|
||||||
|
__typename
|
||||||
id
|
id
|
||||||
number
|
number
|
||||||
archived
|
archived
|
||||||
|
@ -250,6 +254,7 @@ class API::V2::StoredQuery
|
||||||
dateTraitement
|
dateTraitement
|
||||||
dateExpiration
|
dateExpiration
|
||||||
dateSuppressionParUsager
|
dateSuppressionParUsager
|
||||||
|
dateDerniereCorrectionEnAttente @include(if: $includeCorrections)
|
||||||
motivation
|
motivation
|
||||||
motivationAttachment {
|
motivationAttachment {
|
||||||
...FileFragment
|
...FileFragment
|
||||||
|
@ -318,8 +323,8 @@ class API::V2::StoredQuery
|
||||||
dateFermeture
|
dateFermeture
|
||||||
notice { url }
|
notice { url }
|
||||||
deliberation { url }
|
deliberation { url }
|
||||||
demarcheUrl
|
demarcheURL
|
||||||
cadreJuridiqueUrl
|
cadreJuridiqueURL
|
||||||
service @include(if: $includeService) {
|
service @include(if: $includeService) {
|
||||||
...ServiceFragment
|
...ServiceFragment
|
||||||
}
|
}
|
||||||
|
@ -409,6 +414,10 @@ class API::V2::StoredQuery
|
||||||
attachments {
|
attachments {
|
||||||
...FileFragment
|
...FileFragment
|
||||||
}
|
}
|
||||||
|
correction @include(if: $includeCorrections) {
|
||||||
|
reason
|
||||||
|
dateResolution
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment GeoAreaFragment on GeoArea {
|
fragment GeoAreaFragment on GeoArea {
|
||||||
|
@ -455,6 +464,7 @@ class API::V2::StoredQuery
|
||||||
__typename
|
__typename
|
||||||
label
|
label
|
||||||
stringValue
|
stringValue
|
||||||
|
updatedAt
|
||||||
... on DateChamp {
|
... on DateChamp {
|
||||||
date
|
date
|
||||||
}
|
}
|
||||||
|
@ -584,11 +594,13 @@ class API::V2::StoredQuery
|
||||||
|
|
||||||
|
|
||||||
fragment FileFragment on File {
|
fragment FileFragment on File {
|
||||||
|
__typename
|
||||||
filename
|
filename
|
||||||
contentType
|
contentType
|
||||||
checksum
|
checksum
|
||||||
byteSize: byteSizeBigInt
|
byteSize: byteSizeBigInt
|
||||||
url
|
url
|
||||||
|
createdAt
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment AddressFragment on Address {
|
fragment AddressFragment on Address {
|
||||||
|
@ -635,6 +647,7 @@ class API::V2::StoredQuery
|
||||||
fragment PageInfoFragment on PageInfo {
|
fragment PageInfoFragment on PageInfo {
|
||||||
hasPreviousPage
|
hasPreviousPage
|
||||||
hasNextPage
|
hasNextPage
|
||||||
|
startCursor
|
||||||
endCursor
|
endCursor
|
||||||
}
|
}
|
||||||
GRAPHQL
|
GRAPHQL
|
||||||
|
|
|
@ -35,7 +35,7 @@ module Extensions
|
||||||
# is a lazy value (e.g., a Promise – like in our case)
|
# is a lazy value (e.g., a Promise – like in our case)
|
||||||
def after_resolve(value:, **_rest)
|
def after_resolve(value:, **_rest)
|
||||||
if value.respond_to?(:map)
|
if value.respond_to?(:map)
|
||||||
attachments = value.map { after_resolve_attachment(_1) }
|
attachments = value.map { after_resolve_attachment(_1) }.compact
|
||||||
|
|
||||||
if options[:as] == :single
|
if options[:as] == :single
|
||||||
attachments.first
|
attachments.first
|
||||||
|
|
|
@ -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
|
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.
|
Date de la création.
|
||||||
|
@ -1106,7 +1107,8 @@ type DemarcheDescriptor {
|
||||||
"""
|
"""
|
||||||
URL pour commencer la démarche
|
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.
|
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)
|
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.
|
Durée de conservation des dossiers en mois.
|
||||||
|
@ -1129,7 +1132,8 @@ type DemarcheDescriptor {
|
||||||
notice explicative de la démarche
|
notice explicative de la démarche
|
||||||
"""
|
"""
|
||||||
notice: File
|
notice: File
|
||||||
noticeUrl: URL
|
noticeURL: URL
|
||||||
|
noticeUrl: URL @deprecated(reason: "Utilisez le champ `noticeURL` à la place.")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Numero de la démarche.
|
Numero de la démarche.
|
||||||
|
@ -1142,7 +1146,8 @@ type DemarcheDescriptor {
|
||||||
"""
|
"""
|
||||||
URL où les usagers trouvent le lien vers la démarche
|
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.
|
État de la démarche.
|
||||||
|
|
|
@ -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 :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 :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 :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
|
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
|
def demarche_url
|
||||||
Rails.application.routes.url_helpers.commencer_url(path: procedure.path)
|
Rails.application.routes.url_helpers.commencer_url(path: procedure.path)
|
||||||
end
|
end
|
||||||
|
alias demarcheUrl demarche_url
|
||||||
|
|
||||||
def dpo_url
|
def dpo_url
|
||||||
procedure.lien_dpo
|
procedure.lien_dpo
|
||||||
end
|
end
|
||||||
|
alias dpoUrl dpo_url
|
||||||
|
|
||||||
def notice_url
|
def notice_url
|
||||||
procedure.lien_notice
|
procedure.lien_notice
|
||||||
end
|
end
|
||||||
|
alias noticeUrl notice_url
|
||||||
|
|
||||||
def cadre_juridique_url
|
def cadre_juridique_url
|
||||||
procedure.cadre_juridique
|
procedure.cadre_juridique
|
||||||
end
|
end
|
||||||
|
alias cadreJuridiqueUrl cadre_juridique_url
|
||||||
|
|
||||||
def site_web_url
|
def site_web_url
|
||||||
procedure.lien_site_web
|
procedure.lien_site_web
|
||||||
end
|
end
|
||||||
|
alias siteWebUrl site_web_url
|
||||||
|
|
||||||
def number
|
def number
|
||||||
procedure.id
|
procedure.id
|
||||||
|
|
|
@ -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
|
|
|
@ -39,10 +39,10 @@ module ProcedureHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_send_groupe_message?(procedure)
|
def can_send_groupe_message?(procedure)
|
||||||
procedure.dossiers
|
groupe_instructeur_on_procedure_ids = procedure.groupe_instructeurs.active.ids.sort
|
||||||
.state_brouillon
|
groupe_instructeur_on_instructeur_ids = current_instructeur.groupe_instructeurs.active.where(procedure: procedure).ids.sort
|
||||||
.includes(:groupe_instructeur)
|
|
||||||
.exists?(groupe_instructeur: current_instructeur.groupe_instructeurs)
|
groupe_instructeur_on_procedure_ids == groupe_instructeur_on_instructeur_ids
|
||||||
end
|
end
|
||||||
|
|
||||||
def url_or_email_to_lien_dpo(procedure)
|
def url_or_email_to_lien_dpo(procedure)
|
||||||
|
|
|
@ -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
|
|
|
@ -1,5 +0,0 @@
|
||||||
class PipedriveRefusesDealsJob < ApplicationJob
|
|
||||||
def perform(person_id, administration_id)
|
|
||||||
PipedriveService.refuse_demande_from_person(person_id, administration_id)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -5,8 +5,4 @@ module BizDev
|
||||||
def self.full_name(administration_id)
|
def self.full_name(administration_id)
|
||||||
NAME
|
NAME
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.pipedrive_id(administration_id)
|
|
||||||
PIPEDRIVE_ID
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -8,18 +8,4 @@ class ApplicationMailer < ActionMailer::Base
|
||||||
layout 'mailer'
|
layout 'mailer'
|
||||||
|
|
||||||
before_action -> { Sentry.set_tags(mailer: mailer_name, action: action_name) }
|
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
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ class DossierMailer < ApplicationMailer
|
||||||
@dossier = params[:dossier]
|
@dossier = params[:dossier]
|
||||||
I18n.with_locale(@dossier.user_locale) do
|
I18n.with_locale(@dossier.user_locale) do
|
||||||
@service = @dossier.procedure.service
|
@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)
|
@subject = default_i18n_subject(libelle_demarche: @dossier.procedure.libelle)
|
||||||
|
|
||||||
mail(to: @dossier.user_email_for(:notification), subject: @subject) do |format|
|
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
|
I18n.with_locale(dossier.user_locale) do
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@service = dossier.procedure.service
|
@service = dossier.procedure.service
|
||||||
@logo_url = attach_logo(dossier.procedure)
|
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||||
@body = commentaire.body
|
@body = commentaire.body
|
||||||
@subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle)
|
@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
|
I18n.with_locale(dossier.user_locale) do
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@service = dossier.procedure.service
|
@service = dossier.procedure.service
|
||||||
@logo_url = attach_logo(dossier.procedure)
|
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||||
@correction = commentaire.dossier_correction
|
@correction = commentaire.dossier_correction
|
||||||
|
|
||||||
@subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle)
|
@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
|
I18n.with_locale(dossier.user_locale) do
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@service = dossier.procedure.service
|
@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)
|
@subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle)
|
||||||
|
|
||||||
mail(to: dossier.user_email_for(:notification), subject: @subject) do |format|
|
mail(to: dossier.user_email_for(:notification), subject: @subject) do |format|
|
||||||
|
|
|
@ -17,7 +17,7 @@ class NotificationMailer < ApplicationMailer
|
||||||
|
|
||||||
def send_notification
|
def send_notification
|
||||||
@service = @dossier.procedure.service
|
@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?
|
attachments[@attachment[:filename]] = @attachment[:content] if @attachment.present?
|
||||||
I18n.with_locale(@dossier.user_locale) do
|
I18n.with_locale(@dossier.user_locale) do
|
||||||
mail(subject: @subject, to: @email, template_name: 'send_notification')
|
mail(subject: @subject, to: @email, template_name: 'send_notification')
|
||||||
|
|
|
@ -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
|
class Administrateur < ApplicationRecord
|
||||||
UNUSED_ADMIN_THRESHOLD = ENV.fetch('UNUSED_ADMIN_THRESHOLD') { 6 }.to_i.months
|
UNUSED_ADMIN_THRESHOLD = ENV.fetch('UNUSED_ADMIN_THRESHOLD') { 6 }.to_i.months
|
||||||
|
|
||||||
|
@ -29,7 +20,10 @@ class Administrateur < ApplicationRecord
|
||||||
.where.missing(:services)
|
.where.missing(:services)
|
||||||
.left_outer_joins(:administrateurs_procedures) # needed to bypass procedure hidden default scope
|
.left_outer_joins(:administrateurs_procedures) # needed to bypass procedure hidden default scope
|
||||||
.where(administrateurs_procedures: { procedure_id: nil })
|
.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
|
end
|
||||||
|
|
||||||
def self.by_email(email)
|
def self.by_email(email)
|
||||||
|
|
|
@ -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
|
class AdministrateursInstructeur < ApplicationRecord
|
||||||
belongs_to :administrateur
|
belongs_to :administrateur
|
||||||
belongs_to :instructeur
|
belongs_to :instructeur
|
||||||
|
|
|
@ -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
|
class AdministrateursProcedure < ApplicationRecord
|
||||||
belongs_to :administrateur
|
belongs_to :administrateur
|
||||||
belongs_to :procedure
|
belongs_to :procedure
|
||||||
|
|
|
@ -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
|
class APIToken < ApplicationRecord
|
||||||
include ActiveRecord::SecureToken
|
include ActiveRecord::SecureToken
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,4 @@
|
||||||
# == Schema Information
|
# == 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
|
class Archive < ApplicationRecord
|
||||||
include TransientModelsWithPurgeableJobConcern
|
include TransientModelsWithPurgeableJobConcern
|
||||||
|
|
||||||
|
|
|
@ -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
|
class AssignTo < ApplicationRecord
|
||||||
belongs_to :instructeur, optional: false
|
belongs_to :instructeur, optional: false
|
||||||
belongs_to :groupe_instructeur, optional: false
|
belongs_to :groupe_instructeur, optional: false
|
||||||
|
|
|
@ -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
|
class Attestation < ApplicationRecord
|
||||||
belongs_to :dossier, optional: false
|
belongs_to :dossier, optional: false
|
||||||
|
|
||||||
|
|
|
@ -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
|
class AttestationTemplate < ApplicationRecord
|
||||||
include ActionView::Helpers::NumberHelper
|
include ActionView::Helpers::NumberHelper
|
||||||
include TagsSubstitutionConcern
|
include TagsSubstitutionConcern
|
||||||
|
|
|
@ -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
|
class Avis < ApplicationRecord
|
||||||
include EmailSanitizableConcern
|
include EmailSanitizableConcern
|
||||||
|
|
||||||
|
|
|
@ -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
|
class BatchOperation < ApplicationRecord
|
||||||
enum operation: {
|
enum operation: {
|
||||||
accepter: 'accepter',
|
accepter: 'accepter',
|
||||||
|
|
|
@ -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
|
class BillSignature < ApplicationRecord
|
||||||
has_many :dossier_operation_logs
|
has_many :dossier_operation_logs
|
||||||
|
|
||||||
|
|
|
@ -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
|
class BulkMessage < ApplicationRecord
|
||||||
belongs_to :instructeur
|
belongs_to :instructeur
|
||||||
has_and_belongs_to_many :groupe_instructeurs, -> { order(:label) }
|
has_and_belongs_to_many :groupe_instructeurs, -> { order(:label) }
|
||||||
has_one_attached :piece_jointe
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
class Champ < ApplicationRecord
|
||||||
include ChampConditionalConcern
|
include ChampConditionalConcern
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::AddressChamp < Champs::TextChamp
|
||||||
def full_address?
|
def full_address?
|
||||||
data.present?
|
data.present?
|
||||||
|
|
|
@ -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
|
class Champs::AnnuaireEducationChamp < Champs::TextChamp
|
||||||
def fetch_external_data?
|
def fetch_external_data?
|
||||||
true
|
true
|
||||||
|
|
|
@ -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
|
class Champs::BooleanChamp < Champ
|
||||||
TRUE_VALUE = 'true'
|
TRUE_VALUE = 'true'
|
||||||
FALSE_VALUE = 'false'
|
FALSE_VALUE = 'false'
|
||||||
|
|
|
@ -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
|
class Champs::CarteChamp < Champ
|
||||||
# Default map location. Center of the World, ahm, France...
|
# Default map location. Center of the World, ahm, France...
|
||||||
DEFAULT_LON = 2.428462
|
DEFAULT_LON = 2.428462
|
||||||
|
|
|
@ -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
|
class Champs::CheckboxChamp < Champs::BooleanChamp
|
||||||
def for_export
|
def for_export
|
||||||
true? ? 'on' : 'off'
|
true? ? 'on' : 'off'
|
||||||
|
|
|
@ -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
|
class Champs::CiviliteChamp < Champ
|
||||||
validates :value, inclusion: ["M.", "Mme"], allow_nil: true, allow_blank: false
|
validates :value, inclusion: ["M.", "Mme"], allow_nil: true, allow_blank: false
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::CnafChamp < Champs::TextChamp
|
||||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/cnaf-input-validation.middleware.ts
|
# 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 }
|
validates :numero_allocataire, format: { with: /\A\d{1,7}\z/ }, if: -> { code_postal.present? && validation_context != :brouillon }
|
||||||
|
|
|
@ -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
|
class Champs::CommuneChamp < Champs::TextChamp
|
||||||
store_accessor :value_json, :code_departement, :code_postal
|
store_accessor :value_json, :code_departement, :code_postal
|
||||||
before_validation :on_code_postal_change
|
before_validation :on_code_postal_change
|
||||||
|
|
|
@ -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
|
class Champs::DateChamp < Champ
|
||||||
before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill }
|
before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill }
|
||||||
validate :iso_8601
|
validate :iso_8601
|
||||||
|
|
|
@ -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
|
class Champs::DatetimeChamp < Champ
|
||||||
before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill }
|
before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill }
|
||||||
validate :iso_8601
|
validate :iso_8601
|
||||||
|
@ -66,6 +44,6 @@ class Champs::DatetimeChamp < Champ
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid_iso8601?
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
class Champs::DecimalNumberChamp < Champ
|
||||||
validates :value, numericality: {
|
validates :value, numericality: {
|
||||||
allow_nil: true,
|
allow_nil: true,
|
||||||
|
|
|
@ -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
|
class Champs::DepartementChamp < Champs::TextChamp
|
||||||
validate :value_in_departement_names, unless: -> { value.nil? }
|
validate :value_in_departement_names, unless: -> { value.nil? }
|
||||||
validate :external_id_in_departement_codes, unless: -> { external_id.nil? }
|
validate :external_id_in_departement_codes, unless: -> { external_id.nil? }
|
||||||
|
|
|
@ -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
|
class Champs::DgfipChamp < Champs::TextChamp
|
||||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/dgfip-input-validation.middleware.ts
|
# 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 }
|
validates :numero_fiscal, format: { with: /\A\w{13,14}\z/ }, if: -> { reference_avis.present? && validation_context != :brouillon }
|
||||||
|
|
|
@ -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
|
class Champs::DossierLinkChamp < Champ
|
||||||
validate :value_integerable, if: -> { value.present? }, on: :prefill
|
validate :value_integerable, if: -> { value.present? }, on: :prefill
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::DropDownListChamp < Champ
|
||||||
store_accessor :value_json, :other
|
store_accessor :value_json, :other
|
||||||
THRESHOLD_NB_OPTIONS_AS_RADIO = 5
|
THRESHOLD_NB_OPTIONS_AS_RADIO = 5
|
||||||
|
|
|
@ -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
|
class Champs::EmailChamp < Champs::TextChamp
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
class Champs::EpciChamp < Champs::TextChamp
|
||||||
store_accessor :value_json, :code_departement
|
store_accessor :value_json, :code_departement
|
||||||
before_validation :on_departement_change
|
before_validation :on_departement_change
|
||||||
|
|
|
@ -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
|
class Champs::ExplicationChamp < Champs::TextChamp
|
||||||
def search_terms
|
def search_terms
|
||||||
# The user cannot enter any information here so it doesn’t make much sense to search
|
# The user cannot enter any information here so it doesn’t make much sense to search
|
||||||
|
|
|
@ -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
|
class Champs::HeaderSectionChamp < Champ
|
||||||
def level
|
def level
|
||||||
if parent.present?
|
if parent.present?
|
||||||
|
|
|
@ -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
|
class Champs::IbanChamp < Champ
|
||||||
validates_with IbanValidator, if: -> { validation_context != :brouillon }
|
validates_with IbanValidator, if: -> { validation_context != :brouillon }
|
||||||
after_validation :format_iban
|
after_validation :format_iban
|
||||||
|
|
|
@ -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
|
class Champs::IntegerNumberChamp < Champ
|
||||||
validates :value, numericality: {
|
validates :value, numericality: {
|
||||||
only_integer: true,
|
only_integer: true,
|
||||||
|
|
|
@ -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
|
class Champs::LinkedDropDownListChamp < Champ
|
||||||
delegate :primary_options, :secondary_options, to: 'type_de_champ.dynamic_type'
|
delegate :primary_options, :secondary_options, to: 'type_de_champ.dynamic_type'
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::MesriChamp < Champs::TextChamp
|
||||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/mesri-input-validation.middleware.ts
|
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/mesri-input-validation.middleware.ts
|
||||||
store_accessor :value_json, :ine
|
store_accessor :value_json, :ine
|
||||||
|
|
|
@ -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
|
class Champs::MultipleDropDownListChamp < Champ
|
||||||
validate :values_are_in_options, if: -> { value.present? }
|
validate :values_are_in_options, if: -> { value.present? }
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::NumberChamp < Champ
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
class Champs::PaysChamp < Champs::TextChamp
|
||||||
validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: true, allow_blank: false
|
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
|
validates :external_id, inclusion: APIGeoService.countries.pluck(:code), allow_nil: true, allow_blank: false
|
||||||
|
|
|
@ -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
|
class Champs::PhoneChamp < Champs::TextChamp
|
||||||
# We want to allow:
|
# We want to allow:
|
||||||
# * international (e164) phone numbers
|
# * international (e164) phone numbers
|
||||||
|
|
|
@ -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
|
class Champs::PieceJustificativeChamp < Champ
|
||||||
FILE_MAX_SIZE = 200.megabytes
|
FILE_MAX_SIZE = 200.megabytes
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::PoleEmploiChamp < Champs::TextChamp
|
||||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/pole-emploi-input-validation.middleware.ts
|
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/pole-emploi-input-validation.middleware.ts
|
||||||
store_accessor :value_json, :identifiant
|
store_accessor :value_json, :identifiant
|
||||||
|
|
|
@ -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
|
class Champs::RegionChamp < Champs::TextChamp
|
||||||
validate :value_in_region_names, unless: -> { value.nil? }
|
validate :value_in_region_names, unless: -> { value.nil? }
|
||||||
validate :external_id_in_region_codes, unless: -> { external_id.nil? }
|
validate :external_id_in_region_codes, unless: -> { external_id.nil? }
|
||||||
|
|
|
@ -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
|
class Champs::RepetitionChamp < Champ
|
||||||
accepts_nested_attributes_for :champs
|
accepts_nested_attributes_for :champs
|
||||||
delegate :libelle_for_export, to: :type_de_champ
|
delegate :libelle_for_export, to: :type_de_champ
|
||||||
|
|
|
@ -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
|
class Champs::RNAChamp < Champ
|
||||||
include RNAChampAssociationFetchableConcern
|
include RNAChampAssociationFetchableConcern
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::SiretChamp < Champ
|
||||||
include SiretChampEtablissementFetchableConcern
|
include SiretChampEtablissementFetchableConcern
|
||||||
|
|
||||||
|
|
|
@ -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
|
class Champs::TextChamp < Champ
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
class Champs::TextareaChamp < Champs::TextChamp
|
||||||
def for_export
|
def for_export
|
||||||
value.present? ? ActionView::Base.full_sanitizer.sanitize(value) : nil
|
value.present? ? ActionView::Base.full_sanitizer.sanitize(value) : nil
|
||||||
|
|
|
@ -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
|
class Champs::TitreIdentiteChamp < Champ
|
||||||
FILE_MAX_SIZE = 20.megabytes
|
FILE_MAX_SIZE = 20.megabytes
|
||||||
ACCEPTED_FORMATS = ['image/png', 'image/jpeg']
|
ACCEPTED_FORMATS = ['image/png', 'image/jpeg']
|
||||||
|
|
|
@ -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
|
class Champs::YesNoChamp < Champs::BooleanChamp
|
||||||
def yes_input_id
|
def yes_input_id
|
||||||
"#{input_id}-yes"
|
"#{input_id}-yes"
|
||||||
|
|
|
@ -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
|
class Commentaire < ApplicationRecord
|
||||||
include Discard::Model
|
include Discard::Model
|
||||||
|
|
||||||
belongs_to :dossier, inverse_of: :commentaires, touch: true, optional: false
|
belongs_to :dossier, inverse_of: :commentaires, touch: true, optional: false
|
||||||
|
|
||||||
belongs_to :instructeur, inverse_of: :commentaires, optional: true
|
belongs_to :instructeur, inverse_of: :commentaires, optional: true
|
||||||
belongs_to :expert, inverse_of: :commentaires, optional: true
|
belongs_to :expert, inverse_of: :commentaires, optional: true
|
||||||
has_one :dossier_correction, inverse_of: :commentaire, dependent: :nullify
|
has_one :dossier_correction, inverse_of: :commentaire, dependent: :nullify
|
||||||
|
|
|
@ -76,7 +76,8 @@ module DossierCloneConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def clone(user: nil, fork: false)
|
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]
|
relationships = [:individual, :etablissement]
|
||||||
|
|
||||||
cloned_champs = champs
|
cloned_champs = champs
|
||||||
|
@ -95,7 +96,6 @@ module DossierCloneConcern
|
||||||
|
|
||||||
kopy.user = user || original.user
|
kopy.user = user || original.user
|
||||||
kopy.state = Dossier.states.fetch(:brouillon)
|
kopy.state = Dossier.states.fetch(:brouillon)
|
||||||
|
|
||||||
kopy.champs = cloned_champs.values.map do |(_, champ)|
|
kopy.champs = cloned_champs.values.map do |(_, champ)|
|
||||||
champ.dossier = kopy
|
champ.dossier = kopy
|
||||||
champ.parent = cloned_champs[champ.parent_id].second if champ.child?
|
champ.parent = cloned_champs[champ.parent_id].second if champ.child?
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue