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 'mailjet', require: false
|
||||
gem 'matrix' # needed by prawn and not default in ruby 3.1
|
||||
gem 'mini_magick'
|
||||
gem 'net-imap', require: false # See https://github.com/mikel/mail/pull/1439
|
||||
gem 'net-pop', require: false # same
|
||||
gem 'net-smtp', require: false # same
|
||||
|
@ -105,6 +106,7 @@ group :test do
|
|||
gem 'rack_session_access'
|
||||
gem 'rails-controller-testing'
|
||||
gem 'rspec_junit_formatter'
|
||||
gem 'rspec-retry'
|
||||
gem 'selenium-devtools'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'shoulda-matchers', require: false
|
||||
|
@ -114,7 +116,6 @@ group :test do
|
|||
end
|
||||
|
||||
group :development do
|
||||
gem 'annotate'
|
||||
gem 'brakeman', require: false
|
||||
gem 'haml-lint'
|
||||
gem 'letter_opener_web'
|
||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -101,9 +101,6 @@ GEM
|
|||
aes_key_wrap (1.1.0)
|
||||
after_party (1.11.2)
|
||||
anchored (1.1.0)
|
||||
annotate (3.2.0)
|
||||
activerecord (>= 3.2, < 8.0)
|
||||
rake (>= 10.4, < 14.0)
|
||||
ast (2.4.2)
|
||||
attr_required (1.0.1)
|
||||
axe-core-api (4.2.1)
|
||||
|
@ -490,7 +487,7 @@ GEM
|
|||
pry-rails (0.3.9)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (5.0.1)
|
||||
puma (6.1.1)
|
||||
puma (6.3.1)
|
||||
nio4r (~> 2.0)
|
||||
pundit (2.2.0)
|
||||
activesupport (>= 3.0.0)
|
||||
|
@ -604,6 +601,8 @@ GEM
|
|||
rspec-expectations (~> 3.11)
|
||||
rspec-mocks (~> 3.11)
|
||||
rspec-support (~> 3.11)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.12.0)
|
||||
rspec_junit_formatter (0.4.1)
|
||||
rspec-core (>= 2, < 4, != 2.12.0)
|
||||
|
@ -813,7 +812,6 @@ DEPENDENCIES
|
|||
administrate-field-enum
|
||||
after_party
|
||||
anchored
|
||||
annotate
|
||||
axe-core-rspec
|
||||
bcrypt
|
||||
bootsnap (>= 1.4.4)
|
||||
|
@ -872,6 +870,7 @@ DEPENDENCIES
|
|||
matrix
|
||||
memory_profiler
|
||||
mina
|
||||
mini_magick
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
|
@ -898,6 +897,7 @@ DEPENDENCIES
|
|||
rexml
|
||||
rqrcode
|
||||
rspec-rails
|
||||
rspec-retry
|
||||
rspec_junit_formatter
|
||||
rubocop
|
||||
rubocop-performance
|
||||
|
|
|
@ -102,6 +102,10 @@
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.width-max-content {
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
// sizing
|
||||
.width-100 {
|
||||
width: 100%;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// overwrite DSFR style for SimpleFormatComponent, some user use markdown with
|
||||
// ordered list having paragraph between list item
|
||||
.fr-ol-content--override {
|
||||
ol.fr-ol-content--override {
|
||||
list-style-type: decimal;
|
||||
|
||||
li::marker {
|
||||
|
|
|
@ -1,34 +1,6 @@
|
|||
@import "constants";
|
||||
|
||||
#invites-form {
|
||||
padding: $default-padding;
|
||||
text-align: left;
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
margin-top: $default-padding;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight: bold;
|
||||
margin-bottom: $default-spacer;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $default-spacer;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-position: inside;
|
||||
list-style-type: disc;
|
||||
margin-bottom: $default-padding;
|
||||
}
|
||||
|
||||
input[type=email] {
|
||||
margin-bottom: $default-spacer;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-left: $default-spacer;
|
||||
@media (min-width: 48em) {
|
||||
min-width: 400px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
module Dsfr
|
||||
module InputErrorable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
delegate :object, to: :@form
|
||||
delegate :errors, to: :object
|
||||
|
||||
renders_one :hint
|
||||
|
||||
private
|
||||
|
||||
# lookup for edge case from `form.rich_text_area`
|
||||
|
@ -89,6 +92,10 @@ module Dsfr
|
|||
end
|
||||
|
||||
def hint
|
||||
get_slot(:hint).presence || default_hint
|
||||
end
|
||||
|
||||
def default_hint
|
||||
I18n.t("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}")
|
||||
end
|
||||
|
||||
|
@ -101,6 +108,8 @@ module Dsfr
|
|||
end
|
||||
|
||||
def hint?
|
||||
return true if get_slot(:hint).present?
|
||||
|
||||
I18n.exists?("activerecord.attributes.#{object.class.name.underscore}.hints.#{@attribute}")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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.
|
||||
routing_configuration_notice_2_html: |
|
||||
<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>
|
||||
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: |
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
class: 'fr-btn',
|
||||
method: :delete,
|
||||
title: t('.delete_title', defaut_label: @procedure.defaut_groupe_instructeur.label),
|
||||
data: ( @procedure.publiee? ? { disable_with: "Suppression...", confirm: t('.delete_confirmation', defaut_label: @procedure.defaut_groupe_instructeur.label) } : nil)
|
||||
data: ( @procedure.publiee? ? { disable_with: "Suppression…", confirm: t('.delete_confirmation', defaut_label: @procedure.defaut_groupe_instructeur.label) } : nil)
|
||||
|
||||
- elsif @state == 'choix'
|
||||
= form_for :choice,
|
||||
|
|
|
@ -58,8 +58,18 @@ class Procedure::OneGroupeManagementComponent < ApplicationComponent
|
|||
|
||||
def available_values_for_select(targeted_champ)
|
||||
return [] if targeted_champ.is_a?(Logic::Empty)
|
||||
targeted_champ
|
||||
.options(@revision.types_de_champ_public)
|
||||
.map { |tdc| [tdc.first, constant(tdc.first).to_json] }
|
||||
|
||||
case @revision.types_de_champ_public.find_by(stable_id: targeted_champ.stable_id).type_champ
|
||||
when TypeDeChamp.type_champs.fetch(:departements)
|
||||
departements_for_select
|
||||
when TypeDeChamp.type_champs.fetch(:drop_down_list)
|
||||
targeted_champ
|
||||
.options(@revision.types_de_champ_public)
|
||||
.map { |(label, value)| [label, constant(value).to_json] }
|
||||
end
|
||||
end
|
||||
|
||||
def departements_for_select
|
||||
APIGeoService.departements.map { ["#{_1[:code]} – #{_1[:name]}", constant(_1[:code]).to_json] }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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>."
|
||||
add_option: "ajoutés : %{items}"
|
||||
remove_option: "supprimés : %{items}"
|
||||
invalid_routing_rules_alert: "Certains groupes d'instructeurs ont une règle de routage invalide. Veuillez mettre à jour la configuration des groupes d'instructeurs après avoir publié les modifications."
|
||||
public:
|
||||
add: Le champ « %{label} » a été ajouté.
|
||||
add_mandatory: Le champ obligatoire « %{label} » a été ajouté.
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
- if !total_dossiers.zero? && !change.can_rebase?
|
||||
.fr-alert.fr-alert--warning.fr-mt-1v
|
||||
%p= t('.breaking_change', count: total_dossiers)
|
||||
- if removed.present? && change.type_de_champ.used_by_routing_rules?
|
||||
- if (removed.present? || added.present? ) && change.type_de_champ.used_by_routing_rules?
|
||||
.fr-alert.fr-alert--warning.fr-mt-1v
|
||||
= t(".#{prefix}.update_drop_down_options_alert", label: change.label)
|
||||
- when :drop_down_other
|
||||
|
@ -148,3 +148,7 @@
|
|||
- if @private_move_changes.present?
|
||||
- list.with_item do
|
||||
= t(".private.move", count: @private_move_changes.size)
|
||||
- if @previous_revision.procedure.routing_enabled? && @previous_revision.procedure.groupe_instructeurs.any?(&:invalid_rule?)
|
||||
- list.with_item do
|
||||
.fr-alert.fr-alert--warning.fr-mt-1v
|
||||
= t(".invalid_routing_rules_alert")
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
= form_tag(search_admin_procedures_path, data: { turbo: true }, method: :post, class: 'form') do
|
||||
= label_tag :query, 'Rechercher une procédure'
|
||||
= form_tag(search_admin_procedures_path, data: { turbo: true }, method: :post) do
|
||||
.fr-input-group
|
||||
= label_tag :query, class: "fr-label" do
|
||||
Rechercher une démarche
|
||||
%span.fr-hint-text Saisissez au moins 3 lettres
|
||||
|
||||
.notice
|
||||
%p Entrez au minimum 3 lettres
|
||||
|
||||
|
||||
= text_field_tag :query, params[:query], required: true, placeholder: 'politique de la ville', minlength: "3"
|
||||
= text_field_tag :query, params[:query], required: true, placeholder: 'politique de la ville', minlength: "3", class: "fr-input"
|
||||
|
||||
= submit_tag 'Rechercher', class: 'fr-btn'
|
||||
|
||||
|
|
|
@ -40,12 +40,34 @@ module Administrateurs
|
|||
|
||||
tdc = @procedure.active_revision.routable_types_de_champ.find { |tdc| tdc.stable_id == stable_id }
|
||||
|
||||
tdc_options = tdc.options["drop_down_options"].reject(&:empty?)
|
||||
case tdc.type_champ
|
||||
when TypeDeChamp.type_champs.fetch(:departements)
|
||||
tdc_options = APIGeoService.departements.map { ["#{_1[:code]} – #{_1[:name]}", _1[:code]] }
|
||||
tdc_options.each do |code_and_name, code|
|
||||
routing_rule = ds_eq(champ_value(stable_id), constant(code))
|
||||
@procedure
|
||||
.groupe_instructeurs
|
||||
.find_or_create_by(label: code_and_name)
|
||||
.update(instructeurs: [current_administrateur.instructeur], routing_rule:)
|
||||
end
|
||||
|
||||
tdc_options.each do |option_label|
|
||||
gi = @procedure.groupe_instructeurs.find_by({ label: option_label }) || @procedure.groupe_instructeurs
|
||||
.create({ label: option_label, instructeurs: [current_administrateur.instructeur] })
|
||||
gi.update(routing_rule: ds_eq(champ_value(stable_id), constant(gi.label)))
|
||||
when TypeDeChamp.type_champs.fetch(:drop_down_list)
|
||||
tdc_options = tdc.drop_down_options.reject(&:empty?)
|
||||
tdc_options.each do |option_label|
|
||||
routing_rule = ds_eq(champ_value(stable_id), constant(option_label))
|
||||
@procedure
|
||||
.groupe_instructeurs
|
||||
.find_or_create_by(label: option_label)
|
||||
.update(instructeurs: [current_administrateur.instructeur], routing_rule:)
|
||||
end
|
||||
end
|
||||
|
||||
if tdc.drop_down_other?
|
||||
routing_rule = ds_eq(champ_value(stable_id), constant(Champs::DropDownListChamp::OTHER))
|
||||
@procedure
|
||||
.groupe_instructeurs
|
||||
.find_or_create_by(label: 'Autre')
|
||||
.update(instructeurs: [current_administrateur.instructeur], routing_rule:)
|
||||
end
|
||||
|
||||
@procedure.toggle_routing
|
||||
|
|
|
@ -4,7 +4,6 @@ class API::Public::V1::DossiersController < API::Public::V1::BaseController
|
|||
def create
|
||||
dossier = Dossier.new(
|
||||
revision: @procedure.active_revision,
|
||||
groupe_instructeur: @procedure.defaut_groupe_instructeur_for_new_dossier,
|
||||
state: Dossier.states.fetch(:brouillon),
|
||||
prefilled: true
|
||||
)
|
||||
|
|
|
@ -39,7 +39,9 @@ class API::V2::BaseController < ApplicationController
|
|||
|
||||
def api_token
|
||||
if @api_token.nil?
|
||||
@api_token = APIToken.find_and_verify(authorization_bearer_token) || false
|
||||
@api_token = APIToken
|
||||
.find_and_verify(authorization_bearer_token)
|
||||
&.tap { _1.touch(:last_v2_authenticated_at) } || false
|
||||
end
|
||||
@api_token
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ class APIController < ApplicationController
|
|||
def find_administrateur_for_token(procedure)
|
||||
api_token = APIToken.find_and_verify(authorization_bearer_token, procedure.administrateurs)
|
||||
if api_token.present? && api_token.context.fetch(:procedure_ids).include?(procedure.id)
|
||||
api_token.touch(:last_v1_authenticated_at)
|
||||
api_token.administrateur
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
class Champs::OptionsController < ApplicationController
|
||||
include TurboChampsConcern
|
||||
|
||||
before_action :authenticate_logged_user!
|
||||
|
||||
def remove
|
||||
@champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
||||
@champ.remove_option([params[:option]].compact)
|
||||
champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
|
||||
champ.remove_option([params[:option]].compact)
|
||||
champs = champ.private? ? champ.dossier.champs_private_all : champ.dossier.champs_public_all
|
||||
@to_show, @to_hide, @to_update = champs_to_turbo_update({ params[:champ_id] => true }, champs)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -85,7 +85,8 @@ module Instructeurs
|
|||
end
|
||||
|
||||
def personnes_impliquees
|
||||
@following_instructeurs_emails = dossier.followers_instructeurs.map(&:email)
|
||||
# sort following_instructeurs (last follower on top) for the API of Agence de l'Eau Loire-Bretagne
|
||||
@following_instructeurs_emails = dossier.followers_instructeurs.joins(:follows).merge(Follow.order(id: :desc)).map(&:email)
|
||||
previous_followers = dossier.previous_followers_instructeurs - dossier.followers_instructeurs
|
||||
@previous_following_instructeurs_emails = previous_followers.map(&:email)
|
||||
@avis_emails = dossier.experts.map(&:email)
|
||||
|
|
|
@ -224,19 +224,18 @@ module Instructeurs
|
|||
|
||||
def email_usagers
|
||||
@procedure = procedure
|
||||
@commentaire = Commentaire.new
|
||||
@email_usagers_dossiers = email_usagers_dossiers
|
||||
@dossiers_count = @email_usagers_dossiers.count
|
||||
@groupe_instructeurs = email_usagers_groupe_instructeurs_label
|
||||
@bulk_messages = BulkMessage.includes(:groupe_instructeurs).where(groupe_instructeurs: { id: current_instructeur.groupe_instructeur_ids, procedure: procedure })
|
||||
@bulk_messages = BulkMessage.includes(:groupe_instructeurs).where(groupe_instructeurs: { procedure: procedure })
|
||||
@bulk_message = current_instructeur.bulk_messages.build
|
||||
@dossiers_without_groupe_count = procedure.dossiers.state_brouillon.for_groupe_instructeur(nil).count
|
||||
end
|
||||
|
||||
def create_multiple_commentaire
|
||||
@procedure = procedure
|
||||
errors = []
|
||||
|
||||
email_usagers_dossiers.each do |dossier|
|
||||
commentaire = CommentaireService.create(current_instructeur, dossier, commentaire_params)
|
||||
bulk_message = current_instructeur.bulk_messages.build(bulk_message_params)
|
||||
dossiers = procedure.dossiers.state_brouillon.for_groupe_instructeur(nil)
|
||||
dossiers.each do |dossier|
|
||||
commentaire = CommentaireService.create(current_instructeur, dossier, bulk_message_params.except(:targets))
|
||||
if commentaire.errors.empty?
|
||||
commentaire.dossier.update!(last_commentaire_updated_at: Time.zone.now)
|
||||
else
|
||||
|
@ -244,8 +243,15 @@ module Instructeurs
|
|||
end
|
||||
end
|
||||
|
||||
valid_dossiers_count = email_usagers_dossiers.count - errors.count
|
||||
create_bulk_message_mail(valid_dossiers_count, Dossier.states.fetch(:brouillon))
|
||||
valid_dossiers_count = dossiers.count - errors.count
|
||||
bulk_message.assign_attributes(
|
||||
dossier_count: valid_dossiers_count,
|
||||
dossier_state: Dossier.states.fetch(:brouillon),
|
||||
sent_at: Time.zone.now,
|
||||
instructeur_id: current_instructeur.id,
|
||||
groupe_instructeurs: GroupeInstructeur.for_dossiers(dossiers)
|
||||
)
|
||||
bulk_message.save!
|
||||
|
||||
if errors.empty?
|
||||
flash[:notice] = "Tous les messages ont été envoyés avec succès"
|
||||
|
@ -262,18 +268,6 @@ module Instructeurs
|
|||
|
||||
private
|
||||
|
||||
def create_bulk_message_mail(dossier_count, dossier_state)
|
||||
BulkMessage.create(
|
||||
dossier_count: dossier_count,
|
||||
dossier_state: dossier_state,
|
||||
body: commentaire_params[:body],
|
||||
sent_at: Time.zone.now,
|
||||
instructeur_id: current_instructeur.id,
|
||||
piece_jointe: commentaire_params[:piece_jointe],
|
||||
groupe_instructeurs: email_usagers_groupe_instructeurs
|
||||
)
|
||||
end
|
||||
|
||||
def assign_to_params
|
||||
params.require(:assign_to)
|
||||
.permit(:instant_expert_avis_email_notifications_enabled, :instant_email_dossier_notifications_enabled, :instant_email_message_notifications_enabled, :daily_email_notifications_enabled, :weekly_email_notifications_enabled)
|
||||
|
@ -355,20 +349,8 @@ module Instructeurs
|
|||
@current_filters ||= procedure_presentation.filters.fetch(statut, [])
|
||||
end
|
||||
|
||||
def email_usagers_dossiers
|
||||
procedure.dossiers.state_brouillon.where(groupe_instructeur: current_instructeur.groupe_instructeur_ids).includes(:groupe_instructeur)
|
||||
end
|
||||
|
||||
def email_usagers_groupe_instructeurs_label
|
||||
email_usagers_dossiers.map(&:groupe_instructeur).uniq.map(&:label)
|
||||
end
|
||||
|
||||
def email_usagers_groupe_instructeurs
|
||||
email_usagers_dossiers.map(&:groupe_instructeur).uniq
|
||||
end
|
||||
|
||||
def commentaire_params
|
||||
params.require(:commentaire).permit(:body, :piece_jointe)
|
||||
def bulk_message_params
|
||||
params.require(:bulk_message).permit(:body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
end
|
||||
|
||||
@usual_traitement_time = @procedure.stats_usual_traitement_time
|
||||
|
||||
render 'commencer/show'
|
||||
end
|
||||
|
||||
|
@ -94,7 +96,6 @@ module Users
|
|||
def build_prefilled_dossier
|
||||
@prefilled_dossier = Dossier.new(
|
||||
revision: @revision,
|
||||
groupe_instructeur: @procedure.defaut_groupe_instructeur_for_new_dossier,
|
||||
state: Dossier.states.fetch(:brouillon),
|
||||
prefilled: true
|
||||
)
|
||||
|
|
|
@ -375,7 +375,6 @@ module Users
|
|||
|
||||
dossier = Dossier.new(
|
||||
revision: params[:brouillon] ? procedure.draft_revision : procedure.active_revision,
|
||||
groupe_instructeur: procedure.defaut_groupe_instructeur_for_new_dossier,
|
||||
user: current_user,
|
||||
state: Dossier.states.fetch(:brouillon)
|
||||
)
|
||||
|
@ -542,6 +541,7 @@ module Users
|
|||
|
||||
def update_dossier_and_compute_errors
|
||||
errors = []
|
||||
|
||||
@dossier.assign_attributes(champs_public_params)
|
||||
if @dossier.champs_public_all.any?(&:changed_for_autosave?)
|
||||
@dossier.last_champ_updated_at = Time.zone.now
|
||||
|
@ -559,7 +559,6 @@ module Users
|
|||
@dossier.valid?(**submit_validation_options)
|
||||
errors += format_errors(errors: @dossier.errors)
|
||||
errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs)
|
||||
|
||||
errors
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class Users::SessionsController < Devise::SessionsController
|
|||
layout 'login', only: [:new, :create]
|
||||
|
||||
before_action :restore_procedure_context, only: [:new, :create]
|
||||
|
||||
skip_before_action :redirect_if_untrusted, only: [:reset_link_sent]
|
||||
# POST /resource/sign_in
|
||||
def create
|
||||
user = User.find_by(email: params[:user][:email])
|
||||
|
@ -18,6 +18,13 @@ class Users::SessionsController < Devise::SessionsController
|
|||
super
|
||||
end
|
||||
|
||||
def reset_link_sent
|
||||
if send_login_token_or_bufferize(current_instructeur)
|
||||
flash[:notice] = "Nous venons de vous renvoyer un nouveau lien de connexion sécurisée à #{APPLICATION_NAME}"
|
||||
end
|
||||
redirect_to link_sent_path(email: current_instructeur.email)
|
||||
end
|
||||
|
||||
def link_sent
|
||||
if Devise.email_regexp.match?(params[:email])
|
||||
@email = params[:email]
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
require "administrate/base_dashboard"
|
||||
|
||||
class DemandeDashboard < Administrate::BaseDashboard
|
||||
end
|
|
@ -13,6 +13,8 @@ class UserDashboard < Administrate::BaseDashboard
|
|||
confirmed?: Field::Boolean,
|
||||
created_at: Field::DateTime,
|
||||
updated_at: Field::DateTime,
|
||||
blocked_at: Field::DateTime,
|
||||
blocked_reason: Field::String,
|
||||
current_sign_in_at: Field::DateTime,
|
||||
dossiers: Field::HasMany
|
||||
}.freeze
|
||||
|
@ -36,7 +38,9 @@ class UserDashboard < Administrate::BaseDashboard
|
|||
:email,
|
||||
:confirmed?,
|
||||
:current_sign_in_at,
|
||||
:created_at
|
||||
:created_at,
|
||||
:blocked_at,
|
||||
:blocked_reason
|
||||
].freeze
|
||||
|
||||
# FORM_ATTRIBUTES
|
||||
|
|
|
@ -59,6 +59,7 @@ class API::V2::Context < GraphQL::Query::Context
|
|||
{
|
||||
graphql_query: query.query_string,
|
||||
graphql_variables: query.provided_variables&.to_json,
|
||||
graphql_mutation: mutation?,
|
||||
graphql_null_error: errors.any? { _1.is_a? GraphQL::InvalidNullError }.presence,
|
||||
graphql_timeout_error: errors.any? { _1.is_a? GraphQL::Schema::Timeout::TimeoutError }.presence
|
||||
}.compact
|
||||
|
@ -66,6 +67,12 @@ class API::V2::Context < GraphQL::Query::Context
|
|||
|
||||
private
|
||||
|
||||
def mutation?
|
||||
query.lookahead.selections.any? { _1.field.type.respond_to?(:mutation) }.presence
|
||||
rescue
|
||||
false
|
||||
end
|
||||
|
||||
def compute_demarche_authorization(demarche)
|
||||
# procedure_ids and token are passed from graphql controller
|
||||
if self[:procedure_ids].present?
|
||||
|
@ -73,6 +80,7 @@ class API::V2::Context < GraphQL::Query::Context
|
|||
elsif self[:token].present?
|
||||
token = APIToken.find_and_verify(self[:token], demarche.administrateurs)
|
||||
if token.present?
|
||||
token.touch(:last_v2_authenticated_at)
|
||||
Current.user = token.administrateur.user
|
||||
true
|
||||
else
|
||||
|
|
|
@ -138,7 +138,7 @@ class API::V2::Schema < GraphQL::Schema
|
|||
end
|
||||
end
|
||||
|
||||
use Timeout, max_seconds: 10
|
||||
use Timeout, max_seconds: 30
|
||||
use GraphQL::Batch
|
||||
use GraphQL::Backtrace
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ class API::V2::StoredQuery
|
|||
$includeInstructeurs: Boolean = true
|
||||
$includeAvis: Boolean = false
|
||||
$includeMessages: Boolean = false
|
||||
$includeCorrections: Boolean = false
|
||||
$includeGeometry: Boolean = false
|
||||
) {
|
||||
demarche(number: $demarcheNumber) {
|
||||
|
@ -135,6 +136,7 @@ class API::V2::StoredQuery
|
|||
$includeInstructeurs: Boolean = true
|
||||
$includeAvis: Boolean = false
|
||||
$includeMessages: Boolean = false
|
||||
$includeCorrections: Boolean = false
|
||||
$includeGeometry: Boolean = false
|
||||
) {
|
||||
groupeInstructeur(number: $groupeInstructeurNumber) {
|
||||
|
@ -201,6 +203,7 @@ class API::V2::StoredQuery
|
|||
$includeInstructeurs: Boolean = true
|
||||
$includeAvis: Boolean = false
|
||||
$includeMessages: Boolean = false
|
||||
$includeCorrections: Boolean = false
|
||||
$includeGeometry: Boolean = false
|
||||
) {
|
||||
dossier(number: $dossierNumber) {
|
||||
|
@ -239,6 +242,7 @@ class API::V2::StoredQuery
|
|||
}
|
||||
|
||||
fragment DossierFragment on Dossier {
|
||||
__typename
|
||||
id
|
||||
number
|
||||
archived
|
||||
|
@ -250,6 +254,7 @@ class API::V2::StoredQuery
|
|||
dateTraitement
|
||||
dateExpiration
|
||||
dateSuppressionParUsager
|
||||
dateDerniereCorrectionEnAttente @include(if: $includeCorrections)
|
||||
motivation
|
||||
motivationAttachment {
|
||||
...FileFragment
|
||||
|
@ -318,8 +323,8 @@ class API::V2::StoredQuery
|
|||
dateFermeture
|
||||
notice { url }
|
||||
deliberation { url }
|
||||
demarcheUrl
|
||||
cadreJuridiqueUrl
|
||||
demarcheURL
|
||||
cadreJuridiqueURL
|
||||
service @include(if: $includeService) {
|
||||
...ServiceFragment
|
||||
}
|
||||
|
@ -409,6 +414,10 @@ class API::V2::StoredQuery
|
|||
attachments {
|
||||
...FileFragment
|
||||
}
|
||||
correction @include(if: $includeCorrections) {
|
||||
reason
|
||||
dateResolution
|
||||
}
|
||||
}
|
||||
|
||||
fragment GeoAreaFragment on GeoArea {
|
||||
|
@ -455,6 +464,7 @@ class API::V2::StoredQuery
|
|||
__typename
|
||||
label
|
||||
stringValue
|
||||
updatedAt
|
||||
... on DateChamp {
|
||||
date
|
||||
}
|
||||
|
@ -584,11 +594,13 @@ class API::V2::StoredQuery
|
|||
|
||||
|
||||
fragment FileFragment on File {
|
||||
__typename
|
||||
filename
|
||||
contentType
|
||||
checksum
|
||||
byteSize: byteSizeBigInt
|
||||
url
|
||||
createdAt
|
||||
}
|
||||
|
||||
fragment AddressFragment on Address {
|
||||
|
@ -635,6 +647,7 @@ class API::V2::StoredQuery
|
|||
fragment PageInfoFragment on PageInfo {
|
||||
hasPreviousPage
|
||||
hasNextPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
GRAPHQL
|
||||
|
|
|
@ -35,7 +35,7 @@ module Extensions
|
|||
# is a lazy value (e.g., a Promise – like in our case)
|
||||
def after_resolve(value:, **_rest)
|
||||
if value.respond_to?(:map)
|
||||
attachments = value.map { after_resolve_attachment(_1) }
|
||||
attachments = value.map { after_resolve_attachment(_1) }.compact
|
||||
|
||||
if options[:as] == :single
|
||||
attachments.first
|
||||
|
|
|
@ -1066,7 +1066,8 @@ type DemarcheDescriptor {
|
|||
"""
|
||||
URL du cadre juridique qui justifie le droit de collecter les données demandées dans la démarche
|
||||
"""
|
||||
cadreJuridiqueUrl: String
|
||||
cadreJuridiqueURL: String
|
||||
cadreJuridiqueUrl: String @deprecated(reason: "Utilisez le champ `cadreJuridiqueURL` à la place.")
|
||||
|
||||
"""
|
||||
Date de la création.
|
||||
|
@ -1106,7 +1107,8 @@ type DemarcheDescriptor {
|
|||
"""
|
||||
URL pour commencer la démarche
|
||||
"""
|
||||
demarcheUrl: URL
|
||||
demarcheURL: URL
|
||||
demarcheUrl: URL @deprecated(reason: "Utilisez le champ `demarcheURL` à la place.")
|
||||
|
||||
"""
|
||||
Description de la démarche.
|
||||
|
@ -1116,7 +1118,8 @@ type DemarcheDescriptor {
|
|||
"""
|
||||
URL ou email pour contacter le Délégué à la Protection des Données (DPO)
|
||||
"""
|
||||
dpoUrl: String
|
||||
dpoURL: String
|
||||
dpoUrl: String @deprecated(reason: "Utilisez le champ `dpoURL` à la place.")
|
||||
|
||||
"""
|
||||
Durée de conservation des dossiers en mois.
|
||||
|
@ -1129,7 +1132,8 @@ type DemarcheDescriptor {
|
|||
notice explicative de la démarche
|
||||
"""
|
||||
notice: File
|
||||
noticeUrl: URL
|
||||
noticeURL: URL
|
||||
noticeUrl: URL @deprecated(reason: "Utilisez le champ `noticeURL` à la place.")
|
||||
|
||||
"""
|
||||
Numero de la démarche.
|
||||
|
@ -1142,7 +1146,8 @@ type DemarcheDescriptor {
|
|||
"""
|
||||
URL où les usagers trouvent le lien vers la démarche
|
||||
"""
|
||||
siteWebUrl: String
|
||||
siteWebURL: String
|
||||
siteWebUrl: String @deprecated(reason: "Utilisez le champ `siteWebURL` à la place.")
|
||||
|
||||
"""
|
||||
État de la démarche.
|
||||
|
|
|
@ -25,6 +25,12 @@ Cela évite l’accès récursif aux dossiers."
|
|||
|
||||
field :duree_conservation_dossiers, Int, "Durée de conservation des dossiers en mois.", null: false
|
||||
|
||||
field :demarcheUrl, Types::URL, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `demarcheURL` à la place.'
|
||||
field :siteWebUrl, String, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `siteWebURL` à la place.'
|
||||
field :dpoUrl, String, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `dpoURL` à la place.'
|
||||
field :noticeUrl, Types::URL, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `noticeURL` à la place.'
|
||||
field :cadreJuridiqueUrl, String, camelize: false, null: true, deprecation_reason: 'Utilisez le champ `cadreJuridiqueURL` à la place.'
|
||||
|
||||
field :demarche_url, Types::URL, "URL pour commencer la démarche", null: true
|
||||
field :site_web_url, String, "URL où les usagers trouvent le lien vers la démarche", null: true
|
||||
field :dpo_url, String, "URL ou email pour contacter le Délégué à la Protection des Données (DPO)", null: true
|
||||
|
@ -77,22 +83,27 @@ Cela évite l’accès récursif aux dossiers."
|
|||
def demarche_url
|
||||
Rails.application.routes.url_helpers.commencer_url(path: procedure.path)
|
||||
end
|
||||
alias demarcheUrl demarche_url
|
||||
|
||||
def dpo_url
|
||||
procedure.lien_dpo
|
||||
end
|
||||
alias dpoUrl dpo_url
|
||||
|
||||
def notice_url
|
||||
procedure.lien_notice
|
||||
end
|
||||
alias noticeUrl notice_url
|
||||
|
||||
def cadre_juridique_url
|
||||
procedure.cadre_juridique
|
||||
end
|
||||
alias cadreJuridiqueUrl cadre_juridique_url
|
||||
|
||||
def site_web_url
|
||||
procedure.lien_site_web
|
||||
end
|
||||
alias siteWebUrl site_web_url
|
||||
|
||||
def number
|
||||
procedure.id
|
||||
|
|
|
@ -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
|
||||
|
||||
def can_send_groupe_message?(procedure)
|
||||
procedure.dossiers
|
||||
.state_brouillon
|
||||
.includes(:groupe_instructeur)
|
||||
.exists?(groupe_instructeur: current_instructeur.groupe_instructeurs)
|
||||
groupe_instructeur_on_procedure_ids = procedure.groupe_instructeurs.active.ids.sort
|
||||
groupe_instructeur_on_instructeur_ids = current_instructeur.groupe_instructeurs.active.where(procedure: procedure).ids.sort
|
||||
|
||||
groupe_instructeur_on_procedure_ids == groupe_instructeur_on_instructeur_ids
|
||||
end
|
||||
|
||||
def url_or_email_to_lien_dpo(procedure)
|
||||
|
|
|
@ -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)
|
||||
NAME
|
||||
end
|
||||
|
||||
def self.pipedrive_id(administration_id)
|
||||
PIPEDRIVE_ID
|
||||
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'
|
||||
|
||||
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
|
||||
|
|
|
@ -12,7 +12,7 @@ class DossierMailer < ApplicationMailer
|
|||
@dossier = params[:dossier]
|
||||
I18n.with_locale(@dossier.user_locale) do
|
||||
@service = @dossier.procedure.service
|
||||
@logo_url = attach_logo(@dossier.procedure)
|
||||
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||
@subject = default_i18n_subject(libelle_demarche: @dossier.procedure.libelle)
|
||||
|
||||
mail(to: @dossier.user_email_for(:notification), subject: @subject) do |format|
|
||||
|
@ -27,7 +27,7 @@ class DossierMailer < ApplicationMailer
|
|||
I18n.with_locale(dossier.user_locale) do
|
||||
@dossier = dossier
|
||||
@service = dossier.procedure.service
|
||||
@logo_url = attach_logo(dossier.procedure)
|
||||
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||
@body = commentaire.body
|
||||
@subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle)
|
||||
|
||||
|
@ -52,7 +52,7 @@ class DossierMailer < ApplicationMailer
|
|||
I18n.with_locale(dossier.user_locale) do
|
||||
@dossier = dossier
|
||||
@service = dossier.procedure.service
|
||||
@logo_url = attach_logo(dossier.procedure)
|
||||
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||
@correction = commentaire.dossier_correction
|
||||
|
||||
@subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle)
|
||||
|
@ -85,7 +85,7 @@ class DossierMailer < ApplicationMailer
|
|||
I18n.with_locale(dossier.user_locale) do
|
||||
@dossier = dossier
|
||||
@service = dossier.procedure.service
|
||||
@logo_url = attach_logo(dossier.procedure)
|
||||
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||
@subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle)
|
||||
|
||||
mail(to: dossier.user_email_for(:notification), subject: @subject) do |format|
|
||||
|
|
|
@ -17,7 +17,7 @@ class NotificationMailer < ApplicationMailer
|
|||
|
||||
def send_notification
|
||||
@service = @dossier.procedure.service
|
||||
@logo_url = attach_logo(@dossier.procedure)
|
||||
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||
attachments[@attachment[:filename]] = @attachment[:content] if @attachment.present?
|
||||
I18n.with_locale(@dossier.user_locale) do
|
||||
mail(subject: @subject, to: @email, template_name: 'send_notification')
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: administrateurs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# user_id :bigint not null
|
||||
#
|
||||
class Administrateur < ApplicationRecord
|
||||
UNUSED_ADMIN_THRESHOLD = ENV.fetch('UNUSED_ADMIN_THRESHOLD') { 6 }.to_i.months
|
||||
|
||||
|
@ -29,7 +20,10 @@ class Administrateur < ApplicationRecord
|
|||
.where.missing(:services)
|
||||
.left_outer_joins(:administrateurs_procedures) # needed to bypass procedure hidden default scope
|
||||
.where(administrateurs_procedures: { procedure_id: nil })
|
||||
.where("users.last_sign_in_at < ? ", UNUSED_ADMIN_THRESHOLD.ago)
|
||||
.includes(:api_tokens)
|
||||
.where(users: { last_sign_in_at: ..UNUSED_ADMIN_THRESHOLD.ago })
|
||||
.merge(APIToken.where(last_v1_authenticated_at: nil).or(APIToken.where(last_v1_authenticated_at: ..UNUSED_ADMIN_THRESHOLD.ago)))
|
||||
.merge(APIToken.where(last_v2_authenticated_at: nil).or(APIToken.where(last_v2_authenticated_at: ..UNUSED_ADMIN_THRESHOLD.ago)))
|
||||
end
|
||||
|
||||
def self.by_email(email)
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: administrateurs_instructeurs
|
||||
#
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# administrateur_id :integer not null
|
||||
# instructeur_id :integer not null
|
||||
#
|
||||
class AdministrateursInstructeur < ApplicationRecord
|
||||
belongs_to :administrateur
|
||||
belongs_to :instructeur
|
||||
|
|
|
@ -1,13 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: administrateurs_procedures
|
||||
#
|
||||
# manager :boolean
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# administrateur_id :bigint not null
|
||||
# procedure_id :bigint not null
|
||||
#
|
||||
class AdministrateursProcedure < ApplicationRecord
|
||||
belongs_to :administrateur
|
||||
belongs_to :procedure
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: api_tokens
|
||||
#
|
||||
# id :uuid not null, primary key
|
||||
# allowed_procedure_ids :bigint is an Array
|
||||
# encrypted_token :string not null
|
||||
# name :string not null
|
||||
# write_access :boolean default(TRUE), not null
|
||||
# version :integer default(3), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# administrateur_id :bigint not null
|
||||
#
|
||||
class APIToken < ApplicationRecord
|
||||
include ActiveRecord::SecureToken
|
||||
|
||||
|
|
|
@ -1,15 +1,4 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: archives
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# job_status :string not null
|
||||
# key :text not null
|
||||
# month :date
|
||||
# time_span_type :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class Archive < ApplicationRecord
|
||||
include TransientModelsWithPurgeableJobConcern
|
||||
|
||||
|
|
|
@ -1,19 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: assign_tos
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# daily_email_notifications_enabled :boolean default(FALSE), not null
|
||||
# instant_email_dossier_notifications_enabled :boolean default(FALSE), not null
|
||||
# instant_email_message_notifications_enabled :boolean default(FALSE), not null
|
||||
# instant_expert_avis_email_notifications_enabled :boolean default(FALSE)
|
||||
# manager :boolean default(FALSE)
|
||||
# weekly_email_notifications_enabled :boolean default(TRUE), not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# groupe_instructeur_id :bigint
|
||||
# instructeur_id :integer
|
||||
#
|
||||
class AssignTo < ApplicationRecord
|
||||
belongs_to :instructeur, optional: false
|
||||
belongs_to :groupe_instructeur, optional: false
|
||||
|
|
|
@ -1,13 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: attestations
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# title :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# dossier_id :integer not null
|
||||
#
|
||||
class Attestation < ApplicationRecord
|
||||
belongs_to :dossier, optional: false
|
||||
|
||||
|
|
|
@ -1,16 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: attestation_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# activated :boolean
|
||||
# body :text
|
||||
# footer :text
|
||||
# title :text
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# procedure_id :integer
|
||||
#
|
||||
class AttestationTemplate < ApplicationRecord
|
||||
include ActionView::Helpers::NumberHelper
|
||||
include TagsSubstitutionConcern
|
||||
|
|
|
@ -1,23 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: avis
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# answer :text
|
||||
# claimant_type :string
|
||||
# confidentiel :boolean default(FALSE), not null
|
||||
# email :string
|
||||
# introduction :text
|
||||
# question_answer :boolean
|
||||
# question_label :string
|
||||
# reminded_at :datetime
|
||||
# revoked_at :datetime
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# claimant_id :integer not null
|
||||
# dossier_id :integer
|
||||
# experts_procedure_id :bigint
|
||||
#
|
||||
class Avis < ApplicationRecord
|
||||
include EmailSanitizableConcern
|
||||
|
||||
|
|
|
@ -1,20 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: batch_operations
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# failed_dossier_ids :bigint default([]), not null, is an Array
|
||||
# finished_at :datetime
|
||||
# operation :string not null
|
||||
# payload :jsonb not null
|
||||
# run_at :datetime
|
||||
# seen_at :datetime
|
||||
# success_dossier_ids :bigint default([]), not null, is an Array
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# instructeur_id :bigint not null
|
||||
#
|
||||
|
||||
class BatchOperation < ApplicationRecord
|
||||
enum operation: {
|
||||
accepter: 'accepter',
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: bill_signatures
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# digest :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class BillSignature < ApplicationRecord
|
||||
has_many :dossier_operation_logs
|
||||
|
||||
|
|
|
@ -1,18 +1,4 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: bulk_messages
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# body :text not null
|
||||
# dossier_count :integer
|
||||
# dossier_state :string
|
||||
# sent_at :datetime not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# instructeur_id :bigint not null
|
||||
#
|
||||
class BulkMessage < ApplicationRecord
|
||||
belongs_to :instructeur
|
||||
has_and_belongs_to_many :groupe_instructeurs, -> { order(:label) }
|
||||
has_one_attached :piece_jointe
|
||||
end
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champ < ApplicationRecord
|
||||
include ChampConditionalConcern
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::AddressChamp < Champs::TextChamp
|
||||
def full_address?
|
||||
data.present?
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::AnnuaireEducationChamp < Champs::TextChamp
|
||||
def fetch_external_data?
|
||||
true
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::BooleanChamp < Champ
|
||||
TRUE_VALUE = 'true'
|
||||
FALSE_VALUE = 'false'
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::CarteChamp < Champ
|
||||
# Default map location. Center of the World, ahm, France...
|
||||
DEFAULT_LON = 2.428462
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::CheckboxChamp < Champs::BooleanChamp
|
||||
def for_export
|
||||
true? ? 'on' : 'off'
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::CiviliteChamp < Champ
|
||||
validates :value, inclusion: ["M.", "Mme"], allow_nil: true, allow_blank: false
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::CnafChamp < Champs::TextChamp
|
||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/cnaf-input-validation.middleware.ts
|
||||
validates :numero_allocataire, format: { with: /\A\d{1,7}\z/ }, if: -> { code_postal.present? && validation_context != :brouillon }
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::CommuneChamp < Champs::TextChamp
|
||||
store_accessor :value_json, :code_departement, :code_postal
|
||||
before_validation :on_code_postal_change
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::DateChamp < Champ
|
||||
before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill }
|
||||
validate :iso_8601
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::DatetimeChamp < Champ
|
||||
before_validation :convert_to_iso8601, unless: -> { validation_context == :prefill }
|
||||
validate :iso_8601
|
||||
|
@ -66,6 +44,6 @@ class Champs::DatetimeChamp < Champ
|
|||
end
|
||||
|
||||
def valid_iso8601?
|
||||
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}\+\d{2}:\d{2})?$/.match?(value)
|
||||
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}[\+\-]\d{2}:\d{2})?$/.match?(value)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::DecimalNumberChamp < Champ
|
||||
validates :value, numericality: {
|
||||
allow_nil: true,
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::DepartementChamp < Champs::TextChamp
|
||||
validate :value_in_departement_names, unless: -> { value.nil? }
|
||||
validate :external_id_in_departement_codes, unless: -> { external_id.nil? }
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::DgfipChamp < Champs::TextChamp
|
||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/dgfip-input-validation.middleware.ts
|
||||
validates :numero_fiscal, format: { with: /\A\w{13,14}\z/ }, if: -> { reference_avis.present? && validation_context != :brouillon }
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::DossierLinkChamp < Champ
|
||||
validate :value_integerable, if: -> { value.present? }, on: :prefill
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::DropDownListChamp < Champ
|
||||
store_accessor :value_json, :other
|
||||
THRESHOLD_NB_OPTIONS_AS_RADIO = 5
|
||||
|
|
|
@ -1,24 +1,2 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::EmailChamp < Champs::TextChamp
|
||||
end
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::EpciChamp < Champs::TextChamp
|
||||
store_accessor :value_json, :code_departement
|
||||
before_validation :on_departement_change
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::ExplicationChamp < Champs::TextChamp
|
||||
def search_terms
|
||||
# The user cannot enter any information here so it doesn’t make much sense to search
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::HeaderSectionChamp < Champ
|
||||
def level
|
||||
if parent.present?
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::IbanChamp < Champ
|
||||
validates_with IbanValidator, if: -> { validation_context != :brouillon }
|
||||
after_validation :format_iban
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::IntegerNumberChamp < Champ
|
||||
validates :value, numericality: {
|
||||
only_integer: true,
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::LinkedDropDownListChamp < Champ
|
||||
delegate :primary_options, :secondary_options, to: 'type_de_champ.dynamic_type'
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::MesriChamp < Champs::TextChamp
|
||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/mesri-input-validation.middleware.ts
|
||||
store_accessor :value_json, :ine
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::MultipleDropDownListChamp < Champ
|
||||
validate :values_are_in_options, if: -> { value.present? }
|
||||
|
||||
|
|
|
@ -1,24 +1,2 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::NumberChamp < Champ
|
||||
end
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::PaysChamp < Champs::TextChamp
|
||||
validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: true, allow_blank: false
|
||||
validates :external_id, inclusion: APIGeoService.countries.pluck(:code), allow_nil: true, allow_blank: false
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::PhoneChamp < Champs::TextChamp
|
||||
# We want to allow:
|
||||
# * international (e164) phone numbers
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::PieceJustificativeChamp < Champ
|
||||
FILE_MAX_SIZE = 200.megabytes
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::PoleEmploiChamp < Champs::TextChamp
|
||||
# see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/pole-emploi-input-validation.middleware.ts
|
||||
store_accessor :value_json, :identifiant
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::RegionChamp < Champs::TextChamp
|
||||
validate :value_in_region_names, unless: -> { value.nil? }
|
||||
validate :external_id_in_region_codes, unless: -> { external_id.nil? }
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::RepetitionChamp < Champ
|
||||
accepts_nested_attributes_for :champs
|
||||
delegate :libelle_for_export, to: :type_de_champ
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::RNAChamp < Champ
|
||||
include RNAChampAssociationFetchableConcern
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::SiretChamp < Champ
|
||||
include SiretChampEtablissementFetchableConcern
|
||||
|
||||
|
|
|
@ -1,24 +1,2 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::TextChamp < Champ
|
||||
end
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::TextareaChamp < Champs::TextChamp
|
||||
def for_export
|
||||
value.present? ? ActionView::Base.full_sanitizer.sanitize(value) : nil
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::TitreIdentiteChamp < Champ
|
||||
FILE_MAX_SIZE = 20.megabytes
|
||||
ACCEPTED_FORMATS = ['image/png', 'image/jpeg']
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: champs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# data :jsonb
|
||||
# fetch_external_data_exceptions :string is an Array
|
||||
# prefilled :boolean default(FALSE)
|
||||
# private :boolean default(FALSE), not null
|
||||
# rebased_at :datetime
|
||||
# type :string
|
||||
# value :string
|
||||
# value_json :jsonb
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dossier_id :integer
|
||||
# etablissement_id :integer
|
||||
# external_id :string
|
||||
# parent_id :bigint
|
||||
# row_id :string
|
||||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champs::YesNoChamp < Champs::BooleanChamp
|
||||
def yes_input_id
|
||||
"#{input_id}-yes"
|
||||
|
|
|
@ -1,22 +1,6 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: commentaires
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# body :string
|
||||
# discarded_at :datetime
|
||||
# email :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# dossier_id :integer
|
||||
# expert_id :bigint
|
||||
# instructeur_id :bigint
|
||||
#
|
||||
class Commentaire < ApplicationRecord
|
||||
include Discard::Model
|
||||
|
||||
belongs_to :dossier, inverse_of: :commentaires, touch: true, optional: false
|
||||
|
||||
belongs_to :instructeur, inverse_of: :commentaires, optional: true
|
||||
belongs_to :expert, inverse_of: :commentaires, optional: true
|
||||
has_one :dossier_correction, inverse_of: :commentaire, dependent: :nullify
|
||||
|
|
|
@ -76,7 +76,8 @@ module DossierCloneConcern
|
|||
end
|
||||
|
||||
def clone(user: nil, fork: false)
|
||||
dossier_attributes = [:autorisation_donnees, :revision_id, :groupe_instructeur_id]
|
||||
dossier_attributes = [:autorisation_donnees, :revision_id]
|
||||
dossier_attributes += [:groupe_instructeur_id] if fork
|
||||
relationships = [:individual, :etablissement]
|
||||
|
||||
cloned_champs = champs
|
||||
|
@ -95,7 +96,6 @@ module DossierCloneConcern
|
|||
|
||||
kopy.user = user || original.user
|
||||
kopy.state = Dossier.states.fetch(:brouillon)
|
||||
|
||||
kopy.champs = cloned_champs.values.map do |(_, champ)|
|
||||
champ.dossier = kopy
|
||||
champ.parent = cloned_champs[champ.parent_id].second if champ.child?
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue