Merge branch 'dev'
This commit is contained in:
commit
26fd99e942
60 changed files with 692 additions and 417 deletions
2
Gemfile
2
Gemfile
|
@ -145,6 +145,8 @@ group :test do
|
||||||
gem 'capybara-selenium'
|
gem 'capybara-selenium'
|
||||||
# Save a dump of the page when an integration test fails
|
# Save a dump of the page when an integration test fails
|
||||||
gem 'capybara-screenshot'
|
gem 'capybara-screenshot'
|
||||||
|
# Access emails during integration tests
|
||||||
|
gem 'capybara-email'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
|
|
@ -120,6 +120,9 @@ GEM
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
xpath (>= 2.0, < 4.0)
|
xpath (>= 2.0, < 4.0)
|
||||||
|
capybara-email (3.0.1)
|
||||||
|
capybara (>= 2.4, < 4.0)
|
||||||
|
mail
|
||||||
capybara-screenshot (1.0.21)
|
capybara-screenshot (1.0.21)
|
||||||
capybara (>= 1.0, < 4)
|
capybara (>= 1.0, < 4)
|
||||||
launchy
|
launchy
|
||||||
|
@ -812,6 +815,7 @@ DEPENDENCIES
|
||||||
browser
|
browser
|
||||||
byebug
|
byebug
|
||||||
capybara
|
capybara
|
||||||
|
capybara-email
|
||||||
capybara-screenshot
|
capybara-screenshot
|
||||||
capybara-selenium
|
capybara-selenium
|
||||||
carrierwave
|
carrierwave
|
||||||
|
|
27
app/assets/stylesheets/new_design/suivi.scss
Normal file
27
app/assets/stylesheets/new_design/suivi.scss
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
$default-space: 15px;
|
||||||
|
$new-p-margin-bottom: 3 * $default-space;
|
||||||
|
|
||||||
|
.suivi {
|
||||||
|
width: 1040px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-top: $default-space * 2;
|
||||||
|
padding-bottom: $default-space * 2;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
margin-top: -($default-space * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-h2 {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-p {
|
||||||
|
margin-bottom: $new-p-margin-bottom;
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
class Admin::ChangeDossierStateController < AdminController
|
|
||||||
def index
|
|
||||||
@dossier = Dossier.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def change
|
|
||||||
@dossier = Dossier.find(params[:dossier][:id])
|
|
||||||
@dossier.update state: params[:next_state]
|
|
||||||
end
|
|
||||||
|
|
||||||
def check
|
|
||||||
@dossier = Dossier.find(params[:dossier][:id])
|
|
||||||
|
|
||||||
if @dossier.procedure.administrateur.email != current_administrateur.email
|
|
||||||
flash.alert = 'Dossier introuvable'
|
|
||||||
return redirect_to admin_change_dossier_state_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -5,30 +5,30 @@ class Admin::TypesDeChampController < AdminController
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@procedure.types_de_champ.destroy(params[:id])
|
@procedure.types_de_champ.destroy(params[:id])
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
render 'show', format: :js
|
render 'show', format: :js
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render json: { message: 'Champ not found' }, status: 404
|
render json: { message: 'Champ not found' }, status: 404
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @procedure.update(TypesDeChampService.create_update_procedure_params params)
|
setup_type_de_champ_service
|
||||||
|
if @procedure.update(@type_de_champ_service.create_update_procedure_params(params))
|
||||||
flash.now.notice = 'Modifications sauvegardées'
|
flash.now.notice = 'Modifications sauvegardées'
|
||||||
else
|
else
|
||||||
flash.now.alert = @procedure.errors.full_messages.join(', ')
|
flash.now.alert = @procedure.errors.full_messages.join(', ')
|
||||||
end
|
end
|
||||||
create_facade
|
|
||||||
render 'show', format: :js
|
render 'show', format: :js
|
||||||
end
|
end
|
||||||
|
|
||||||
def move_up
|
def move_up
|
||||||
index = params[:index].to_i - 1
|
index = params[:index].to_i - 1
|
||||||
if @procedure.switch_types_de_champ index
|
if @procedure.switch_types_de_champ(index)
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
render 'show', format: :js
|
render 'show', format: :js
|
||||||
else
|
else
|
||||||
render json: {}, status: 400
|
render json: {}, status: 400
|
||||||
|
@ -36,8 +36,8 @@ class Admin::TypesDeChampController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def move_down
|
def move_down
|
||||||
if @procedure.switch_types_de_champ params[:index].to_i
|
if @procedure.switch_types_de_champ(params[:index].to_i)
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
render 'show', format: :js
|
render 'show', format: :js
|
||||||
else
|
else
|
||||||
render json: {}, status: 400
|
render json: {}, status: 400
|
||||||
|
@ -46,7 +46,7 @@ class Admin::TypesDeChampController < AdminController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def create_facade
|
def setup_type_de_champ_service
|
||||||
@types_de_champ_facade = AdminTypesDeChampFacades.new false, @procedure
|
@type_de_champ_service = TypesDeChampService.new(@procedure)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,28 +5,31 @@ class Admin::TypesDeChampPrivateController < AdminController
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@procedure.types_de_champ_private.destroy(params[:id])
|
@procedure.types_de_champ_private.destroy(params[:id])
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
render 'admin/types_de_champ/show', format: :js
|
render 'admin/types_de_champ/show', format: :js
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render json: { message: 'Champ not found' }, status: 404
|
render json: { message: 'Champ not found' }, status: 404
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
render 'admin/types_de_champ/show'
|
render 'admin/types_de_champ/show'
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@procedure.update(TypesDeChampService.create_update_procedure_params params, true)
|
setup_type_de_champ_service
|
||||||
create_facade
|
if @procedure.update(@type_de_champ_service.create_update_procedure_params(params))
|
||||||
flash.now.notice = 'Modifications sauvegardées'
|
flash.now.notice = 'Modifications sauvegardées'
|
||||||
|
else
|
||||||
|
flash.now.alert = @procedure.errors.full_messages.join(', ')
|
||||||
|
end
|
||||||
render 'admin/types_de_champ/show', format: :js
|
render 'admin/types_de_champ/show', format: :js
|
||||||
end
|
end
|
||||||
|
|
||||||
def move_up
|
def move_up
|
||||||
index = params[:index].to_i - 1
|
index = params[:index].to_i - 1
|
||||||
if @procedure.switch_types_de_champ_private index
|
if @procedure.switch_types_de_champ_private(index)
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
render 'admin/types_de_champ/show', format: :js
|
render 'admin/types_de_champ/show', format: :js
|
||||||
else
|
else
|
||||||
render json: {}, status: 400
|
render json: {}, status: 400
|
||||||
|
@ -34,8 +37,8 @@ class Admin::TypesDeChampPrivateController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def move_down
|
def move_down
|
||||||
if @procedure.switch_types_de_champ_private params[:index].to_i
|
if @procedure.switch_types_de_champ_private(params[:index].to_i)
|
||||||
create_facade
|
setup_type_de_champ_service
|
||||||
render 'admin/types_de_champ/show', format: :js
|
render 'admin/types_de_champ/show', format: :js
|
||||||
else
|
else
|
||||||
render json: {}, status: 400
|
render json: {}, status: 400
|
||||||
|
@ -44,7 +47,7 @@ class Admin::TypesDeChampPrivateController < AdminController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def create_facade
|
def setup_type_de_champ_service
|
||||||
@types_de_champ_facade = AdminTypesDeChampFacades.new true, @procedure
|
@type_de_champ_service = TypesDeChampService.new(@procedure, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ class API::V1::DossiersController < APIController
|
||||||
DEFAULT_PAGE_SIZE = 100
|
DEFAULT_PAGE_SIZE = 100
|
||||||
|
|
||||||
def index
|
def index
|
||||||
dossiers = @procedure.dossiers.state_not_brouillon.page(params[:page]).per(per_page)
|
dossiers = @dossiers.page(params[:page]).per(per_page)
|
||||||
|
|
||||||
render json: { dossiers: dossiers.map{ |dossier| DossiersSerializer.new(dossier) }, pagination: pagination(dossiers) }, status: 200
|
render json: { dossiers: dossiers.map{ |dossier| DossiersSerializer.new(dossier) }, pagination: pagination(dossiers) }, status: 200
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
@ -12,7 +12,7 @@ class API::V1::DossiersController < APIController
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
dossier = @procedure.dossiers.find(params[:id])
|
dossier = @dossiers.for_api.find(params[:id])
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json { render json: { dossier: DossierSerializer.new(dossier).as_json }, status: 200 }
|
format.json { render json: { dossier: DossierSerializer.new(dossier).as_json }, status: 200 }
|
||||||
|
@ -36,12 +36,14 @@ class API::V1::DossiersController < APIController
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_procedure_and_check_token
|
def fetch_procedure_and_check_token
|
||||||
@procedure = Procedure.includes(:administrateur).find(params[:procedure_id])
|
@procedure = Procedure.for_api.find(params[:procedure_id])
|
||||||
|
|
||||||
if !valid_token_for_administrateur?(@procedure.administrateur)
|
if !valid_token_for_administrateur?(@procedure.administrateur)
|
||||||
render json: {}, status: :unauthorized
|
render json: {}, status: :unauthorized
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@dossiers = @procedure.dossiers.state_not_brouillon
|
||||||
|
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render json: {}, status: :not_found
|
render json: {}, status: :not_found
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ class API::V1::ProceduresController < APIController
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_procedure_and_check_token
|
def fetch_procedure_and_check_token
|
||||||
@procedure = Procedure.includes(:administrateur).find(params[:id])
|
@procedure = Procedure.for_api.find(params[:id])
|
||||||
|
|
||||||
if !valid_token_for_administrateur?(@procedure.administrateur)
|
if !valid_token_for_administrateur?(@procedure.administrateur)
|
||||||
render json: {}, status: :unauthorized
|
render json: {}, status: :unauthorized
|
||||||
|
|
|
@ -4,8 +4,10 @@ module Manager
|
||||||
before_action :default_params
|
before_action :default_params
|
||||||
|
|
||||||
def default_params
|
def default_params
|
||||||
params[:order] ||= "created_at"
|
params[resource_name] ||= {
|
||||||
params[:direction] ||= "desc"
|
order: "created_at",
|
||||||
|
direction: "desc"
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -55,4 +55,7 @@ class RootController < ApplicationController
|
||||||
|
|
||||||
@dossier = Dossier.new(champs: all_champs)
|
@dossier = Dossier.new(champs: all_champs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def suivi
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,8 +25,24 @@ class Users::ConfirmationsController < Devise::ConfirmationsController
|
||||||
# super(resource_name)
|
# super(resource_name)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
# If the user clicks the confirmation link before the maximum delay,
|
||||||
|
# they will be signed in directly.
|
||||||
|
def sign_in_after_confirmation?(resource)
|
||||||
|
# Avoid keeping auto-sign-in links in users inboxes for too long.
|
||||||
|
# 95% of users confirm their account within two hours.
|
||||||
|
auto_sign_in_timeout = 2.hours
|
||||||
|
resource.confirmation_sent_at + auto_sign_in_timeout > DateTime.current
|
||||||
|
end
|
||||||
|
|
||||||
# The path used after confirmation.
|
# The path used after confirmation.
|
||||||
# def after_confirmation_path_for(resource_name, resource)
|
def after_confirmation_path_for(resource_name, resource)
|
||||||
# super(resource_name, resource)
|
if sign_in_after_confirmation?(resource)
|
||||||
# end
|
resource.remember_me = true
|
||||||
|
sign_in(resource)
|
||||||
|
resource.force_sync_credentials
|
||||||
|
after_sign_in_path_for(resource_name)
|
||||||
|
else
|
||||||
|
super(resource_name, resource)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
class DossierDecorator < Draper::Decorator
|
class DossierDecorator < Draper::Decorator
|
||||||
include Rails.application.routes.url_helpers
|
|
||||||
|
|
||||||
delegate :current_page, :limit_value, :total_pages
|
delegate :current_page, :limit_value, :total_pages
|
||||||
delegate_all
|
delegate_all
|
||||||
|
|
||||||
|
@ -11,12 +9,4 @@ class DossierDecorator < Draper::Decorator
|
||||||
def last_update
|
def last_update
|
||||||
updated_at.strftime('%d/%m/%Y %H:%M')
|
updated_at.strftime('%d/%m/%Y %H:%M')
|
||||||
end
|
end
|
||||||
|
|
||||||
def display_state
|
|
||||||
DossierDecorator.case_state_fr state
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.case_state_fr(state = self.state)
|
|
||||||
h.t("activerecord.attributes.dossier.state.#{state}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
class AdminTypesDeChampFacades
|
|
||||||
include Rails.application.routes.url_helpers
|
|
||||||
|
|
||||||
def initialize(private, procedure)
|
|
||||||
@private = private
|
|
||||||
@procedure = procedure
|
|
||||||
end
|
|
||||||
|
|
||||||
def private
|
|
||||||
@private
|
|
||||||
end
|
|
||||||
|
|
||||||
def active
|
|
||||||
@private ? 'Annotations privées' : 'Champs'
|
|
||||||
end
|
|
||||||
|
|
||||||
def url
|
|
||||||
@private ? admin_procedure_types_de_champ_private_path(@procedure) : admin_procedure_types_de_champ_path(@procedure)
|
|
||||||
end
|
|
||||||
|
|
||||||
def types_de_champ
|
|
||||||
@private ? @procedure.types_de_champ_private_ordered.decorate : @procedure.types_de_champ_ordered.decorate
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_type_de_champ
|
|
||||||
TypeDeChamp.new(private: @private).decorate
|
|
||||||
end
|
|
||||||
|
|
||||||
def fields_for_var
|
|
||||||
@private ? :types_de_champ_private : :types_de_champ
|
|
||||||
end
|
|
||||||
|
|
||||||
def move_up_url(ff)
|
|
||||||
@private ? move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_up_admin_procedure_types_de_champ_path(@procedure, ff.index)
|
|
||||||
end
|
|
||||||
|
|
||||||
def move_down_url(ff)
|
|
||||||
@private ? move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_down_admin_procedure_types_de_champ_path(@procedure, ff.index)
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete_url(ff)
|
|
||||||
@private ? admin_procedure_type_de_champ_private_path(@procedure, ff.object.id) : admin_procedure_type_de_champ_path(@procedure, ff.object.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_button_id
|
|
||||||
@private ? :add_type_de_champ_private : :add_type_de_champ
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,55 +0,0 @@
|
||||||
class DossierFacades
|
|
||||||
# TODO rechercher en fonction de la personne/email
|
|
||||||
def initialize(dossier_id, email, champ_id = nil)
|
|
||||||
@dossier = Dossier.find(dossier_id)
|
|
||||||
@champ_id = champ_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def dossier
|
|
||||||
@dossier.decorate
|
|
||||||
end
|
|
||||||
|
|
||||||
def champs
|
|
||||||
@dossier.champs
|
|
||||||
end
|
|
||||||
|
|
||||||
def etablissement
|
|
||||||
@dossier.etablissement
|
|
||||||
end
|
|
||||||
|
|
||||||
def types_de_pieces_justificatives
|
|
||||||
@dossier.types_de_piece_justificative.order('order_place ASC')
|
|
||||||
end
|
|
||||||
|
|
||||||
def champ_id
|
|
||||||
@champ_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def commentaires
|
|
||||||
@dossier.commentaires.where(champ_id: @champ_id).decorate
|
|
||||||
end
|
|
||||||
|
|
||||||
def procedure
|
|
||||||
@dossier.procedure
|
|
||||||
end
|
|
||||||
|
|
||||||
def invites
|
|
||||||
@dossier.invites
|
|
||||||
end
|
|
||||||
|
|
||||||
def champs_private
|
|
||||||
@dossier.champs_private
|
|
||||||
end
|
|
||||||
|
|
||||||
def individual
|
|
||||||
@dossier.individual
|
|
||||||
end
|
|
||||||
|
|
||||||
def commentaires_files
|
|
||||||
PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
def followers
|
|
||||||
@dossier.followers_gestionnaires
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -26,4 +26,26 @@ module DossierHelper
|
||||||
def dossier_submission_is_closed?(dossier)
|
def dossier_submission_is_closed?(dossier)
|
||||||
dossier.brouillon? && dossier.procedure.archivee?
|
dossier.brouillon? && dossier.procedure.archivee?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dossier_display_state(dossier, lower: false)
|
||||||
|
state = I18n.t(dossier.state, scope: [:activerecord, :attributes, :dossier, :state])
|
||||||
|
lower ? state.downcase : state
|
||||||
|
end
|
||||||
|
|
||||||
|
def dossier_legacy_state(dossier)
|
||||||
|
case dossier.state
|
||||||
|
when Dossier.states.fetch(:en_construction)
|
||||||
|
'initiated'
|
||||||
|
when Dossier.states.fetch(:en_instruction)
|
||||||
|
'received'
|
||||||
|
when Dossier.states.fetch(:accepte)
|
||||||
|
'closed'
|
||||||
|
when Dossier.states.fetch(:refuse)
|
||||||
|
'refused'
|
||||||
|
when Dossier.states.fetch(:sans_suite)
|
||||||
|
'without_continuation'
|
||||||
|
else
|
||||||
|
dossier.state
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
module TypeDeChampHelper
|
|
||||||
TOGGLES = {
|
|
||||||
TypeDeChamp.type_champs.fetch(:piece_justificative) => :champ_pj?,
|
|
||||||
TypeDeChamp.type_champs.fetch(:siret) => :champ_siret?,
|
|
||||||
TypeDeChamp.type_champs.fetch(:linked_drop_down_list) => :champ_linked_dropdown?,
|
|
||||||
TypeDeChamp.type_champs.fetch(:integer_number) => :champ_integer_number?
|
|
||||||
}
|
|
||||||
|
|
||||||
def tdc_options
|
|
||||||
tdcs = TypeDeChamp.type_de_champs_list_fr
|
|
||||||
|
|
||||||
tdcs.select! do |tdc|
|
|
||||||
toggle = TOGGLES[tdc.last]
|
|
||||||
toggle.blank? || Flipflop.send(toggle)
|
|
||||||
end
|
|
||||||
|
|
||||||
tdcs
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -5,6 +5,11 @@ class Champ < ApplicationRecord
|
||||||
has_one_attached :piece_justificative_file
|
has_one_attached :piece_justificative_file
|
||||||
has_one :virus_scan
|
has_one :virus_scan
|
||||||
|
|
||||||
|
# We declare champ specific relationships (Champs::CarteChamp and Champs::SiretChamp)
|
||||||
|
# here because otherwise we can't easily use includes in our queries.
|
||||||
|
has_many :geo_areas, dependent: :destroy
|
||||||
|
belongs_to :etablissement, dependent: :destroy
|
||||||
|
|
||||||
delegate :libelle, :type_champ, :order_place, :mandatory?, :description, :drop_down_list, to: :type_de_champ
|
delegate :libelle, :type_champ, :order_place, :mandatory?, :description, :drop_down_list, to: :type_de_champ
|
||||||
|
|
||||||
scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) }
|
scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) }
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
class Champs::CarteChamp < Champ
|
class Champs::CarteChamp < Champ
|
||||||
has_many :geo_areas, foreign_key: :champ_id, dependent: :destroy
|
|
||||||
|
|
||||||
# We are not using scopes here as we want to access
|
# We are not using scopes here as we want to access
|
||||||
# the following collections on unsaved records.
|
# the following collections on unsaved records.
|
||||||
def cadastres
|
def cadastres
|
||||||
|
|
|
@ -37,7 +37,6 @@ class Champs::SiretChamp < Champ
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
belongs_to :etablissement, dependent: :destroy
|
|
||||||
accepts_nested_attributes_for :etablissement, allow_destroy: true, update_only: true
|
accepts_nested_attributes_for :etablissement, allow_destroy: true, update_only: true
|
||||||
|
|
||||||
def search_terms
|
def search_terms
|
||||||
|
|
|
@ -59,6 +59,26 @@ class Dossier < ApplicationRecord
|
||||||
scope :with_champs, -> { includes(champs: :type_de_champ) }
|
scope :with_champs, -> { includes(champs: :type_de_champ) }
|
||||||
scope :nearing_end_of_retention, -> (duration = '1 month') { joins(:procedure).where("en_instruction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - now() < interval ?", duration) }
|
scope :nearing_end_of_retention, -> (duration = '1 month') { joins(:procedure).where("en_instruction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - now() < interval ?", duration) }
|
||||||
|
|
||||||
|
scope :for_api, -> {
|
||||||
|
includes(commentaires: [],
|
||||||
|
champs: [
|
||||||
|
:geo_areas,
|
||||||
|
:etablissement,
|
||||||
|
piece_justificative_file_attachment: :blob
|
||||||
|
],
|
||||||
|
champs_private: [
|
||||||
|
:geo_areas,
|
||||||
|
:etablissement,
|
||||||
|
piece_justificative_file_attachment: :blob
|
||||||
|
],
|
||||||
|
pieces_justificatives: [],
|
||||||
|
quartier_prioritaires: [],
|
||||||
|
cadastres: [],
|
||||||
|
etablissement: [],
|
||||||
|
individual: [],
|
||||||
|
user: [])
|
||||||
|
}
|
||||||
|
|
||||||
accepts_nested_attributes_for :individual
|
accepts_nested_attributes_for :individual
|
||||||
|
|
||||||
delegate :siret, :siren, to: :etablissement, allow_nil: true
|
delegate :siret, :siren, to: :etablissement, allow_nil: true
|
||||||
|
@ -225,16 +245,6 @@ class Dossier < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def statut
|
|
||||||
if accepte?
|
|
||||||
'accepté'
|
|
||||||
elsif sans_suite?
|
|
||||||
'classé sans suite'
|
|
||||||
elsif refuse?
|
|
||||||
'refusé'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_geometry
|
def user_geometry
|
||||||
if json_latlngs.present?
|
if json_latlngs.present?
|
||||||
UserGeometry.new(json_latlngs)
|
UserGeometry.new(json_latlngs)
|
||||||
|
@ -288,23 +298,6 @@ class Dossier < ApplicationRecord
|
||||||
DossierMailer.notify_deletion_to_user(deleted_dossier, user.email).deliver_later
|
DossierMailer.notify_deletion_to_user(deleted_dossier, user.email).deliver_later
|
||||||
end
|
end
|
||||||
|
|
||||||
def old_state_value
|
|
||||||
case state
|
|
||||||
when Dossier.states.fetch(:en_construction)
|
|
||||||
'initiated'
|
|
||||||
when Dossier.states.fetch(:en_instruction)
|
|
||||||
'received'
|
|
||||||
when Dossier.states.fetch(:accepte)
|
|
||||||
'closed'
|
|
||||||
when Dossier.states.fetch(:refuse)
|
|
||||||
'refused'
|
|
||||||
when Dossier.states.fetch(:sans_suite)
|
|
||||||
'without_continuation'
|
|
||||||
else
|
|
||||||
state
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def update_state_dates
|
def update_state_dates
|
||||||
|
|
|
@ -47,6 +47,16 @@ class Procedure < ApplicationRecord
|
||||||
scope :cloned_from_library, -> { where(cloned_from_library: true) }
|
scope :cloned_from_library, -> { where(cloned_from_library: true) }
|
||||||
scope :avec_lien, -> { where.not(path: nil) }
|
scope :avec_lien, -> { where.not(path: nil) }
|
||||||
|
|
||||||
|
scope :for_api, -> {
|
||||||
|
includes(
|
||||||
|
:administrateur,
|
||||||
|
:types_de_champ_private,
|
||||||
|
:types_de_champ,
|
||||||
|
:types_de_piece_justificative,
|
||||||
|
:module_api_carto
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
validates :libelle, presence: true, allow_blank: false, allow_nil: false
|
validates :libelle, presence: true, allow_blank: false, allow_nil: false
|
||||||
validates :description, presence: true, allow_blank: false, allow_nil: false
|
validates :description, presence: true, allow_blank: false, allow_nil: false
|
||||||
validate :check_juridique
|
validate :check_juridique
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class DossierSerializer < ActiveModel::Serializer
|
class DossierSerializer < ActiveModel::Serializer
|
||||||
|
include DossierHelper
|
||||||
|
|
||||||
attributes :id,
|
attributes :id,
|
||||||
:created_at,
|
:created_at,
|
||||||
:updated_at,
|
:updated_at,
|
||||||
|
@ -42,11 +44,11 @@ class DossierSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def state
|
def state
|
||||||
object.old_state_value
|
dossier_legacy_state(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
def simplified_state
|
def simplified_state
|
||||||
object.decorate.display_state
|
dossier_display_state(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
def initiated_at
|
def initiated_at
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class DossierTableExportSerializer < ActiveModel::Serializer
|
class DossierTableExportSerializer < ActiveModel::Serializer
|
||||||
|
include DossierHelper
|
||||||
|
|
||||||
attributes :id,
|
attributes :id,
|
||||||
:created_at,
|
:created_at,
|
||||||
:updated_at,
|
:updated_at,
|
||||||
|
@ -22,20 +24,7 @@ class DossierTableExportSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def state
|
def state
|
||||||
case object.state
|
dossier_legacy_state(object)
|
||||||
when Dossier.states.fetch(:en_construction)
|
|
||||||
'initiated'
|
|
||||||
when Dossier.states.fetch(:en_instruction)
|
|
||||||
'received'
|
|
||||||
when Dossier.states.fetch(:accepte)
|
|
||||||
'closed'
|
|
||||||
when Dossier.states.fetch(:refuse)
|
|
||||||
'refused'
|
|
||||||
when Dossier.states.fetch(:sans_suite)
|
|
||||||
'without_continuation'
|
|
||||||
else
|
|
||||||
object.state
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def initiated_at
|
def initiated_at
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class DossiersSerializer < ActiveModel::Serializer
|
class DossiersSerializer < ActiveModel::Serializer
|
||||||
|
include DossierHelper
|
||||||
|
|
||||||
attributes :id,
|
attributes :id,
|
||||||
:updated_at,
|
:updated_at,
|
||||||
:initiated_at,
|
:initiated_at,
|
||||||
|
@ -13,6 +15,6 @@ class DossiersSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def state
|
def state
|
||||||
object.old_state_value
|
dossier_legacy_state(object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,71 @@
|
||||||
class TypesDeChampService
|
class TypesDeChampService
|
||||||
def self.create_update_procedure_params(params, private = false)
|
include Rails.application.routes.url_helpers
|
||||||
attributes = (private ? 'types_de_champ_private_attributes' : 'types_de_champ_attributes')
|
|
||||||
|
|
||||||
|
TOGGLES = {
|
||||||
|
TypeDeChamp.type_champs.fetch(:piece_justificative) => :champ_pj?,
|
||||||
|
TypeDeChamp.type_champs.fetch(:siret) => :champ_siret?,
|
||||||
|
TypeDeChamp.type_champs.fetch(:linked_drop_down_list) => :champ_linked_dropdown?,
|
||||||
|
TypeDeChamp.type_champs.fetch(:integer_number) => :champ_integer_number?
|
||||||
|
}
|
||||||
|
|
||||||
|
def options
|
||||||
|
types_de_champ = TypeDeChamp.type_de_champs_list_fr
|
||||||
|
|
||||||
|
types_de_champ.select! do |tdc|
|
||||||
|
toggle = TOGGLES[tdc.last]
|
||||||
|
toggle.blank? || Flipflop.send(toggle)
|
||||||
|
end
|
||||||
|
|
||||||
|
types_de_champ
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(procedure, private_type_de_champ = false)
|
||||||
|
@procedure = procedure
|
||||||
|
@private_type_de_champ = private_type_de_champ
|
||||||
|
end
|
||||||
|
|
||||||
|
def private?
|
||||||
|
@private_type_de_champ
|
||||||
|
end
|
||||||
|
|
||||||
|
def active
|
||||||
|
private? ? 'Annotations privées' : 'Champs'
|
||||||
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
private? ? admin_procedure_types_de_champ_private_path(@procedure) : admin_procedure_types_de_champ_path(@procedure)
|
||||||
|
end
|
||||||
|
|
||||||
|
def types_de_champ
|
||||||
|
private? ? @procedure.types_de_champ_private_ordered.decorate : @procedure.types_de_champ_ordered.decorate
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_type_de_champ
|
||||||
|
TypeDeChamp.new(private: private?).decorate
|
||||||
|
end
|
||||||
|
|
||||||
|
def fields_for_var
|
||||||
|
private? ? :types_de_champ_private : :types_de_champ
|
||||||
|
end
|
||||||
|
|
||||||
|
def move_up_url(ff)
|
||||||
|
private? ? move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_up_admin_procedure_types_de_champ_path(@procedure, ff.index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def move_down_url(ff)
|
||||||
|
private? ? move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_down_admin_procedure_types_de_champ_path(@procedure, ff.index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_url(ff)
|
||||||
|
private? ? admin_procedure_type_de_champ_private_path(@procedure, ff.object.id) : admin_procedure_type_de_champ_path(@procedure, ff.object.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_button_id
|
||||||
|
private? ? :add_type_de_champ_private : :add_type_de_champ
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_update_procedure_params(params)
|
||||||
|
attributes = "#{fields_for_var}_attributes"
|
||||||
params_with_ordered_champs = order_champs(params, attributes)
|
params_with_ordered_champs = order_champs(params, attributes)
|
||||||
|
|
||||||
parameters = params_with_ordered_champs
|
parameters = params_with_ordered_champs
|
||||||
|
@ -21,13 +85,13 @@ class TypesDeChampService
|
||||||
])
|
])
|
||||||
|
|
||||||
parameters[attributes].each do |index, param|
|
parameters[attributes].each do |index, param|
|
||||||
param[:private] = private
|
param[:private] = private?
|
||||||
if param[:libelle].empty?
|
if param[:libelle].empty?
|
||||||
parameters[attributes].delete(index.to_s)
|
parameters[attributes].delete(index.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
if param['drop_down_list_attributes'] && param['drop_down_list_attributes']['value']
|
if param['drop_down_list_attributes'] && param['drop_down_list_attributes']['value']
|
||||||
param['drop_down_list_attributes']['value'] = self.clean_value (param['drop_down_list_attributes']['value'])
|
param['drop_down_list_attributes']['value'] = clean_value(param['drop_down_list_attributes']['value'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -36,7 +100,7 @@ class TypesDeChampService
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def self.order_champs(params, attributes)
|
def order_champs(params, attributes)
|
||||||
# It's OK to use an unsafe hash here because the params will then go through
|
# It's OK to use an unsafe hash here because the params will then go through
|
||||||
# require / permit methods in #create_update_procedure_params
|
# require / permit methods in #create_update_procedure_params
|
||||||
tdcas = params[:procedure][attributes].to_unsafe_hash.to_a
|
tdcas = params[:procedure][attributes].to_unsafe_hash.to_a
|
||||||
|
@ -64,15 +128,15 @@ class TypesDeChampService
|
||||||
params
|
params
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.is_number?(value)
|
def is_number?(value)
|
||||||
(value =~ /^[0-9]+$/) == 0
|
(value =~ /^[0-9]+$/) == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.tdca_order_changed?(tdca)
|
def tdca_order_changed?(tdca)
|
||||||
(tdca[:order_place].to_i + 1) != tdca[:custom_order_place].to_i
|
(tdca[:order_place].to_i + 1) != tdca[:custom_order_place].to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.clean_value(value)
|
def clean_value(value)
|
||||||
value.split("\r\n").map(&:strip).join("\r\n")
|
value.split("\r\n").map(&:strip).join("\r\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
.center
|
|
||||||
%h2 Outil de changement d'état d'un dossier
|
|
||||||
|
|
||||||
%h4.text-success
|
|
||||||
Changement effectué
|
|
||||||
|
|
||||||
= form_for @dossier, url: 'change_dossier_state', action: :put do |f|
|
|
||||||
Dossier ID :
|
|
||||||
= @dossier.id
|
|
||||||
%br
|
|
||||||
État :
|
|
||||||
= @dossier.decorate.display_state
|
|
||||||
|
|
||||||
%br
|
|
||||||
%br
|
|
||||||
= link_to 'Réaliser un autre dossier', 'change_dossier_state'
|
|
|
@ -1,17 +0,0 @@
|
||||||
.center
|
|
||||||
%h2 Outil de changement d'état d'un dossier
|
|
||||||
|
|
||||||
= form_for @dossier, url: 'change_dossier_state', action: :put do |f|
|
|
||||||
Dossier ID :
|
|
||||||
= @dossier.id
|
|
||||||
= f.hidden_field :id
|
|
||||||
%br
|
|
||||||
État :
|
|
||||||
= @dossier.decorate.display_state
|
|
||||||
%br
|
|
||||||
État souhaité :
|
|
||||||
%select{ id: :next_state, name: :next_state }
|
|
||||||
- Dossier.states.each do |state|
|
|
||||||
%option{ value: state[0] }
|
|
||||||
= DossierDecorator.case_state_fr state[1]
|
|
||||||
= f.submit 'Valider'
|
|
|
@ -1,7 +0,0 @@
|
||||||
.center
|
|
||||||
%h2 Outil de changement d'état d'un dossier
|
|
||||||
|
|
||||||
= form_for @dossier, url: 'change_dossier_state', action: :post do |f|
|
|
||||||
Dossier ID
|
|
||||||
= f.text_field :id
|
|
||||||
= f.submit 'Vérifier état'
|
|
|
@ -1,4 +1,4 @@
|
||||||
= f.fields_for @types_de_champ_facade.fields_for_var, types_de_champ, remote: true do |ff|
|
= f.fields_for type_de_champ_service.fields_for_var, types_de_champ, remote: true do |ff|
|
||||||
- type_champ = ff.object.object.type_champ
|
- type_champ = ff.object.object.type_champ
|
||||||
|
|
||||||
.form-inline{ class: (type_champ == TypeDeChamp.type_champs.fetch(:header_section) ? 'header-section' : nil) }
|
.form-inline{ class: (type_champ == TypeDeChamp.type_champs.fetch(:header_section) ? 'header-section' : nil) }
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
.form-group.type
|
.form-group.type
|
||||||
%h4 Type
|
%h4 Type
|
||||||
= ff.select :type_champ, tdc_options, {}, { class: 'form-control type-champ' }
|
= ff.select :type_champ, type_de_champ_service.options, {}, { class: 'form-control type-champ' }
|
||||||
|
|
||||||
.form-group.description
|
.form-group.description
|
||||||
%h4 Description
|
%h4 Description
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
- if ff.object.id.present?
|
- if ff.object.id.present?
|
||||||
.form-group
|
.form-group
|
||||||
%br
|
%br
|
||||||
= ff.object.button_up(index: ff.index, url: @types_de_champ_facade.move_up_url(ff), private: @types_de_champ_facade.private)
|
= ff.object.button_up(index: ff.index, url: type_de_champ_service.move_up_url(ff), private: type_de_champ_service.private?)
|
||||||
= ff.object.button_down(index: ff.index, url: @types_de_champ_facade.move_down_url(ff), private: @types_de_champ_facade.private)
|
= ff.object.button_down(index: ff.index, url: type_de_champ_service.move_down_url(ff), private: type_de_champ_service.private?)
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
%h4 position
|
%h4 position
|
||||||
|
@ -76,10 +76,10 @@
|
||||||
%br
|
%br
|
||||||
- if ff.object.id.nil?
|
- if ff.object.id.nil?
|
||||||
= f.button 'Ajouter le champ',
|
= f.button 'Ajouter le champ',
|
||||||
id: @types_de_champ_facade.add_button_id,
|
id: type_de_champ_service.add_button_id,
|
||||||
class: 'btn btn-success',
|
class: 'btn btn-success',
|
||||||
data: { disable: true }
|
data: { disable: true }
|
||||||
- else
|
- else
|
||||||
= link_to("", @types_de_champ_facade.delete_url(ff), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) )
|
= link_to("", type_de_champ_service.delete_url(ff), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) )
|
||||||
|
|
||||||
%div{ style: 'background-color: rgb(204, 204, 204); height: 1px; margin: 30px auto;' }
|
%div{ style: 'background-color: rgb(204, 204, 204); height: 1px; margin: 30px auto;' }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
= form_for [:admin, @procedure], url: @types_de_champ_facade.url, remote: true do |f|
|
= form_for [:admin, procedure], url: type_de_champ_service.url, remote: true do |f|
|
||||||
= render partial: 'admin/types_de_champ/fields', locals: { types_de_champ: @types_de_champ_facade.types_de_champ, f: f }
|
= render partial: 'admin/types_de_champ/fields', locals: { type_de_champ_service: type_de_champ_service, types_de_champ: type_de_champ_service.types_de_champ, f: f }
|
||||||
|
|
||||||
= f.button 'Enregistrer',
|
= f.button 'Enregistrer',
|
||||||
id: :save,
|
id: :save,
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
|
|
||||||
%hr
|
%hr
|
||||||
#new_type_de_champ
|
#new_type_de_champ
|
||||||
= render partial: 'admin/types_de_champ/fields', locals: { types_de_champ: @types_de_champ_facade.new_type_de_champ, f: f }
|
= render partial: 'admin/types_de_champ/fields', locals: { type_de_champ_service: type_de_champ_service, types_de_champ: type_de_champ_service.new_type_de_champ, f: f }
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
.row.white-back
|
.row.white-back
|
||||||
#liste-champ
|
#liste-champ
|
||||||
= render partial: 'admin/types_de_champ/form'
|
= render partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, type_de_champ_service: @type_de_champ_service }
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<%= render_flash(timeout: 3000, sticky: true) %>
|
<%= render_flash(timeout: 3000, sticky: true) %>
|
||||||
<%= render_to_element('#liste-champ', partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, types_de_champ: @types_de_champ }) %>
|
<%= render_to_element('#liste-champ', partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, type_de_champ_service: @type_de_champ_service }) %>
|
||||||
|
|
15
app/views/layouts/_matomo.html.haml
Normal file
15
app/views/layouts/_matomo.html.haml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
:javascript
|
||||||
|
var _paq = _paq || [];
|
||||||
|
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||||
|
_paq.push(["setCookieDomain", "*.www.demarches-simplifiees.fr"]);
|
||||||
|
_paq.push(["setDomains", ["*.www.demarches-simplifiees.fr"]]);
|
||||||
|
_paq.push(["setDoNotTrack", true]);
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {
|
||||||
|
var u="//stats.data.gouv.fr/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||||
|
_paq.push(['setSiteId', '73']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
|
@ -16,10 +16,13 @@
|
||||||
= javascript_include_tag 'application', defer: true, 'data-turbolinks-track': 'reload'
|
= javascript_include_tag 'application', defer: true, 'data-turbolinks-track': 'reload'
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
|
|
||||||
|
= render partial: "layouts/matomo"
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
DATA = [{
|
DATA = [{
|
||||||
sentry: #{raw(sentry_config)}
|
sentry: #{raw(sentry_config)}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
%body{ class: browser.platform.ios? ? 'ios' : nil }
|
%body{ class: browser.platform.ios? ? 'ios' : nil }
|
||||||
= render partial: 'layouts/outdated_browser_banner'
|
= render partial: 'layouts/outdated_browser_banner'
|
||||||
= render partial: 'layouts/pre_maintenance'
|
= render partial: 'layouts/pre_maintenance'
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
= render partial: 'layouts/left_panels/left_panel_admin_procedurescontroller_navbar', locals: { active: @types_de_champ_facade.active }
|
= render partial: 'layouts/left_panels/left_panel_admin_procedurescontroller_navbar', locals: { active: @type_de_champ_service.active }
|
||||||
|
|
|
@ -21,10 +21,14 @@
|
||||||
- if Rails.env.development?
|
- if Rails.env.development?
|
||||||
= stylesheet_link_tag :xray
|
= stylesheet_link_tag :xray
|
||||||
|
|
||||||
|
- if !current_user
|
||||||
|
= render partial: "layouts/matomo"
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
DATA = [{
|
DATA = [{
|
||||||
sentry: #{raw(sentry_config)}
|
sentry: #{raw(sentry_config)}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
%body{ class: browser.platform.ios? ? 'ios' : nil }
|
%body{ class: browser.platform.ios? ? 'ios' : nil }
|
||||||
.page-wrapper
|
.page-wrapper
|
||||||
= render partial: "layouts/outdated_browser_banner"
|
= render partial: "layouts/outdated_browser_banner"
|
||||||
|
|
|
@ -46,4 +46,4 @@
|
||||||
.print-header
|
.print-header
|
||||||
= dossier.procedure.libelle.truncate_words(10)
|
= dossier.procedure.libelle.truncate_words(10)
|
||||||
>
|
>
|
||||||
= "Dossier nº #{dossier.id} (#{dossier.statut})"
|
= "Dossier nº #{dossier.id} (#{dossier_display_state(dossier, lower: true)})"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
- if dossier.en_construction? || dossier.en_instruction?
|
- if dossier.en_construction? || dossier.en_instruction?
|
||||||
%span.dropdown
|
%span.dropdown
|
||||||
%button.button.primary.dropdown-button
|
%button.button.primary.dropdown-button
|
||||||
= dossier.decorate.display_state
|
= dossier_display_state dossier
|
||||||
.dropdown-content.fade-in-down
|
.dropdown-content.fade-in-down
|
||||||
%ul.dropdown-items
|
%ul.dropdown-items
|
||||||
- if dossier.en_construction?
|
- if dossier.en_construction?
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
- if dossier.motivation.present? || dossier.attestation.present?
|
- if dossier.motivation.present? || dossier.attestation.present?
|
||||||
%span.dropdown
|
%span.dropdown
|
||||||
%button.button.dropdown-button{ class: button_or_label_class(dossier) }
|
%button.button.dropdown-button{ class: button_or_label_class(dossier) }
|
||||||
= dossier.statut
|
= dossier_display_state(dossier, lower: true)
|
||||||
.dropdown-content.fade-in-down.terminated
|
.dropdown-content.fade-in-down.terminated
|
||||||
- if dossier.motivation.present?
|
- if dossier.motivation.present?
|
||||||
%h4 Motivation
|
%h4 Motivation
|
||||||
|
@ -67,4 +67,4 @@
|
||||||
= link_to "Voir l'attestation", attestation_gestionnaire_dossier_path(dossier.procedure, dossier), target: '_blank', class: 'button'
|
= link_to "Voir l'attestation", attestation_gestionnaire_dossier_path(dossier.procedure, dossier), target: '_blank', class: 'button'
|
||||||
- else
|
- else
|
||||||
%span.label{ class: button_or_label_class(dossier) }
|
%span.label{ class: button_or_label_class(dossier) }
|
||||||
= dossier.statut
|
= dossier_display_state(dossier, lower: true)
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
= link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
|
= link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
|
||||||
%li.footer-link
|
%li.footer-link
|
||||||
= link_to "Mentions légales", MENTIONS_LEGALES_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
|
= link_to "Mentions légales", MENTIONS_LEGALES_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
|
||||||
|
%li.footer-link
|
||||||
|
= link_to "Suivi d'audience et vie privée", suivi_path, :class => "footer-link"
|
||||||
|
|
||||||
%li.footer-column
|
%li.footer-column
|
||||||
%ul.footer-links
|
%ul.footer-links
|
||||||
|
|
23
app/views/root/suivi.html.haml
Normal file
23
app/views/root/suivi.html.haml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
- content_for(:title, 'Suivi')
|
||||||
|
|
||||||
|
.suivi
|
||||||
|
%h1.new-h1 Cookies déposés et configuration du suivi
|
||||||
|
|
||||||
|
%p.new-p
|
||||||
|
Ce site dépose un petit fichier texte (un « cookie ») sur votre ordinateur lorsque vous le consultez. Cela nous permet de mesurer le nombre de visites et de comprendre quelles sont les pages les plus consultées.
|
||||||
|
|
||||||
|
%iframe{ :src => MATOMO_IFRAME_URL }
|
||||||
|
|
||||||
|
%h2.new-h2 Ce site n’affiche pas de bannière de consentement aux cookies, pourquoi ?
|
||||||
|
%p.new-p
|
||||||
|
C’est vrai, vous n’avez pas eu à cliquer sur un bloc qui recouvre la moitié de la page pour dire que vous êtes d’accord avec le dépôt de cookies.
|
||||||
|
%br
|
||||||
|
%br
|
||||||
|
Rien d'exceptionnel, pas de passe-droit. Nous respectons simplement la loi, qui dit que certains outils de suivi d’audience, correctement configurés pour respecter la vie privée, sont exemptés d’autorisation préalable.
|
||||||
|
%br
|
||||||
|
%br
|
||||||
|
Nous utilisons pour cela <a href="https://matomo.org/" target="_blank" >Matomo</a>, un outil <a href="https://matomo.org/free-software/" target="_blank">libre</a>, paramétré pour être en conformité avec la <a href="https://www.cnil.fr/fr/solutions-pour-la-mesure-daudience">recommandation « Cookies » </a>de la CNIL. Cela signifie que votre adresse IP, par exemple, est anonymisée avant d’être enregistrée. Il est donc impossible d’associer vos visites sur ce site à votre personne.
|
||||||
|
|
||||||
|
%h2.new-h2 Je contribue à enrichir vos données, puis-je y accéder ?
|
||||||
|
%p.new-p
|
||||||
|
Bien sûr ! Les statistiques d’usage sont en accès libre sur <a href="https://stats.data.gouv.fr/index.php?module=MultiSites&action=index&idSite=1&period=range&date=previous30&updated=1#?idSite=1&period=range&date=previous30&category=Dashboard_Dashboard&subcategory=1&module=MultiSites&action=index" target="_blank">stats.data.gouv.fr</a>.
|
|
@ -39,7 +39,6 @@ Rails.application.configure do
|
||||||
# Print deprecation notices to the stderr.
|
# Print deprecation notices to the stderr.
|
||||||
config.active_support.deprecation = :stderr
|
config.active_support.deprecation = :stderr
|
||||||
|
|
||||||
config.action_mailer.delivery_method = :test
|
|
||||||
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
||||||
Rails.application.routes.default_url_options = {
|
Rails.application.routes.default_url_options = {
|
||||||
host: 'localhost:3000',
|
host: 'localhost:3000',
|
||||||
|
|
|
@ -22,3 +22,4 @@ MENTIONS_LEGALES_URL = [CGU_URL, "4-mentions-legales"].join("#")
|
||||||
API_DOC_URL = [DOC_URL, "pour-aller-plus-loin", "api"].join("/")
|
API_DOC_URL = [DOC_URL, "pour-aller-plus-loin", "api"].join("/")
|
||||||
WEBHOOK_DOC_URL = [DOC_URL, "pour-aller-plus-loin", "webhook"].join("/")
|
WEBHOOK_DOC_URL = [DOC_URL, "pour-aller-plus-loin", "webhook"].join("/")
|
||||||
FAQ_URL = "https://faq.demarches-simplifiees.fr"
|
FAQ_URL = "https://faq.demarches-simplifiees.fr"
|
||||||
|
MATOMO_IFRAME_URL = "https://stats.data.gouv.fr/index.php?module=CoreAdminHome&action=optOut&language=fr&&fontColor=333333&fontSize=16px&fontFamily=Muli"
|
||||||
|
|
|
@ -128,6 +128,7 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
get "patron" => "root#patron"
|
get "patron" => "root#patron"
|
||||||
|
get "suivi" => "root#suivi"
|
||||||
|
|
||||||
get "contact", to: "support#index"
|
get "contact", to: "support#index"
|
||||||
post "contact", to: "support#create"
|
post "contact", to: "support#create"
|
||||||
|
@ -172,10 +173,6 @@ Rails.application.routes.draw do
|
||||||
get 'procedures/path_list' => 'procedures#path_list'
|
get 'procedures/path_list' => 'procedures#path_list'
|
||||||
get 'procedures/available' => 'procedures#check_availability'
|
get 'procedures/available' => 'procedures#check_availability'
|
||||||
|
|
||||||
get 'change_dossier_state' => 'change_dossier_state#index'
|
|
||||||
post 'change_dossier_state' => 'change_dossier_state#check'
|
|
||||||
patch 'change_dossier_state' => 'change_dossier_state#change'
|
|
||||||
|
|
||||||
resources :procedures do
|
resources :procedures do
|
||||||
collection do
|
collection do
|
||||||
get 'new_from_existing' => 'procedures#new_from_existing', as: :new_from_existing
|
get 'new_from_existing' => 'procedures#new_from_existing', as: :new_from_existing
|
||||||
|
|
|
@ -67,6 +67,9 @@ namespace :'2018_07_31_nutriscore' do
|
||||||
libelle: 'Numéro SIRET'
|
libelle: 'Numéro SIRET'
|
||||||
)
|
)
|
||||||
) do |d, target_tdc|
|
) do |d, target_tdc|
|
||||||
|
if d.etablissement.present?
|
||||||
|
d.etablissement.signature = d.etablissement.sign
|
||||||
|
end
|
||||||
target_tdc.champ.create(
|
target_tdc.champ.create(
|
||||||
value: d.etablissement&.siret,
|
value: d.etablissement&.siret,
|
||||||
etablissement: d.etablissement,
|
etablissement: d.etablissement,
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
require Rails.root.join("lib", "tasks", "task_helper")
|
||||||
|
|
||||||
|
namespace :after_party do
|
||||||
|
desc 'Deployment task: approve / reject dossiers for procedure 8670'
|
||||||
|
task mass_process_procedure_8670_dossiers: :environment do
|
||||||
|
class MassProcessProcedure8670
|
||||||
|
DOSSIER_IDS_TO_ACCEPT = [
|
||||||
|
194722, 172178, 170186, 177122, 171783, 173930, 176042, 183202, 192081, 170387,
|
||||||
|
171136, 171765, 173743, 173784, 173802, 173904, 173915, 171744, 173945, 170839,
|
||||||
|
173954, 173967, 173990, 174003, 172217, 170449, 176603, 175921, 172634, 179048,
|
||||||
|
180970, 181508, 182035, 181526, 178543, 170822, 170782, 186579, 187928, 188183,
|
||||||
|
188399, 176860, 170614, 194011, 194100, 196307, 200282, 171544, 201953, 176316,
|
||||||
|
205882, 205907, 205962, 178940, 181650, 202114, 180333, 174687, 192439, 169826,
|
||||||
|
170121, 169894, 170635, 170626, 171896, 171993, 171935, 172028, 172087, 172094,
|
||||||
|
172138, 172206, 172456, 172468, 172533, 172627, 172758, 172834, 172845, 172879,
|
||||||
|
172884, 173411, 173662, 172256, 173909, 191259, 197681, 200041, 177306, 202624,
|
||||||
|
203230, 204556, 205785, 198252, 170227, 173513, 172296, 174292, 174483, 174492,
|
||||||
|
175076, 176540, 177177, 177322, 183210, 183498, 184353, 195189, 195967, 186147,
|
||||||
|
170799, 178152, 177440, 184132, 169967, 175335, 177364, 179365, 197527, 172820,
|
||||||
|
187060, 200326, 169921, 183622, 174745, 175484, 174512, 180860, 189163, 170054,
|
||||||
|
170106, 206667, 170263, 173759, 169879, 170632, 190310, 170325, 170336, 170650,
|
||||||
|
171520, 171050, 170414, 173804, 173911, 173947, 178986, 172030, 177428, 182875,
|
||||||
|
198458, 199080, 172489, 200406, 204297, 171184, 171265, 171338, 171347, 172620,
|
||||||
|
173162, 171939, 171597, 173878, 173758, 175861, 175923, 176851, 176957, 172479,
|
||||||
|
183279, 177429, 185382, 185586, 188898, 172840, 180340, 195351, 171135, 170583,
|
||||||
|
171680, 174150, 175066, 177164, 172951, 170623, 172863, 178732, 178268, 179848,
|
||||||
|
179896, 179923, 179283, 180083, 185764, 192455, 190329, 197121, 169897, 170005,
|
||||||
|
170023, 170127, 170399, 170371, 170351, 170519, 170654, 170680, 170774, 170781,
|
||||||
|
171892, 169828, 171989, 172070, 171952, 171923, 172184, 174859, 175560, 175865,
|
||||||
|
172922, 171889, 173550, 181501, 179897, 185241, 190364, 193743, 178551, 199361,
|
||||||
|
173739, 169885, 169893, 171777, 179338, 179818, 170339, 178090, 187012, 191063,
|
||||||
|
179911, 195101, 177916, 170242, 173537, 173895, 173700, 174642, 174749, 174880,
|
||||||
|
174818, 175011, 174863, 175422, 175644, 177797, 177829, 174276, 200208, 204312,
|
||||||
|
204356, 179106, 177928, 180376, 181086, 180048, 192202, 194193, 204479, 204979,
|
||||||
|
183388, 185549
|
||||||
|
]
|
||||||
|
|
||||||
|
DOSSIER_IDS_TO_REJECT = [
|
||||||
|
172516, 177423, 177002, 179031, 176856, 179193, 179237, 179333, 179912, 179949,
|
||||||
|
181001, 185704, 185710, 177001, 186898, 175420, 175412, 195668, 174463, 175347,
|
||||||
|
174606, 176668, 176749, 177007, 177037, 174306, 177373, 174496, 174583, 205297,
|
||||||
|
191646, 178553, 184288, 174296, 199563, 202567, 180596, 194441, 196523, 183504,
|
||||||
|
190011, 184563, 175047, 177243, 174108, 174423, 170552, 171931, 170955, 170415,
|
||||||
|
170652, 170145, 170044, 169841, 171280, 177569, 174711, 180357, 180554, 175594,
|
||||||
|
181370, 180370, 180279, 182877, 188432, 183516, 191845, 184965, 198962, 199250,
|
||||||
|
202324, 205887, 172006, 196073, 197861, 198389, 188855, 198639, 203881, 205520,
|
||||||
|
205626, 206468, 196904, 206619, 206730, 175088, 191405, 173038, 195082, 185849,
|
||||||
|
188454, 188501, 188713, 171057, 177541, 177882, 178185, 178951, 178962, 178997,
|
||||||
|
179090, 179234, 173959, 177621, 174022, 181414, 181895, 183081, 175935, 175951,
|
||||||
|
176156, 176200, 176506, 176567, 173898, 173906, 173905, 173932, 173810, 173949,
|
||||||
|
173961, 174033, 172939, 174227, 172362, 173008, 174979, 173396, 173196, 172143,
|
||||||
|
173790, 173745, 173779, 172151, 170332, 171424, 171434, 170459, 171635, 171689,
|
||||||
|
170409, 171429, 171940, 170266, 172632, 172742, 170689, 206612, 169877, 170402,
|
||||||
|
170563, 170605, 170658, 170653, 170699, 170511, 170835, 183559, 187911, 188163,
|
||||||
|
188685, 188702, 170678, 183994, 173899, 194530, 194873, 194433, 173971, 174004,
|
||||||
|
174239, 174430, 175849, 175850, 176265, 176630, 176789, 175946, 172407, 177398,
|
||||||
|
170027, 170002, 170404, 173678, 170655, 170328, 170405, 170686, 171106, 171763,
|
||||||
|
172317, 172763, 172880, 173250, 174938, 170714, 175798, 175899, 176015, 176041,
|
||||||
|
176258, 176341, 176909, 176944, 174031, 180109, 170316, 174100, 174540, 175910,
|
||||||
|
177872, 178117, 179092, 183923, 175005, 185795, 186580, 181383, 189186, 194998,
|
||||||
|
177475, 174446, 180508, 181216, 181290, 181905, 191344, 187745, 192016, 193188,
|
||||||
|
170201, 170288, 170568
|
||||||
|
]
|
||||||
|
|
||||||
|
def run
|
||||||
|
rake_puts "Running deploy task 'mass_process_procedure_8670_dossiers'\n"
|
||||||
|
|
||||||
|
reject_dossiers
|
||||||
|
accept_dossiers
|
||||||
|
|
||||||
|
AfterParty::TaskRecord.create version: '20181106170434'
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject_dossiers
|
||||||
|
rake_puts "Rejecting dossiers\n"
|
||||||
|
|
||||||
|
dossiers_for_traitement.where(id: DOSSIER_IDS_TO_REJECT).find_each do |dossier|
|
||||||
|
if skip_dossier?(dossier)
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
dossier.update(
|
||||||
|
state: Dossier.states.fetch(:refuse),
|
||||||
|
motivation: "Malheureusement, votre dossier n'a pas été tiré au sort",
|
||||||
|
processed_at: Time.zone.now
|
||||||
|
)
|
||||||
|
NotificationMailer.send_refused_notification(dossier).deliver_later
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_dossiers
|
||||||
|
rake_puts "Accepting dossiers\n"
|
||||||
|
|
||||||
|
dossiers_for_traitement.where(id: DOSSIER_IDS_TO_ACCEPT).find_each do |dossier|
|
||||||
|
if skip_dossier?(dossier)
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
dossier.update(
|
||||||
|
state: Dossier.states.fetch(:accepte),
|
||||||
|
processed_at: Time.zone.now
|
||||||
|
)
|
||||||
|
dossier.attestation = dossier.build_attestation
|
||||||
|
dossier.save
|
||||||
|
NotificationMailer.send_closed_notification(dossier).deliver_later
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def dossiers_for_traitement
|
||||||
|
Dossier.includes(:procedure, :user, :etablissement, :champs, :champs_private)
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_dossier?(dossier)
|
||||||
|
if dossier.procedure_id != 8670
|
||||||
|
rake_puts "Skipping dossier #{dossier.id} (wrong procedure)\n"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if !dossier.en_instruction?
|
||||||
|
rake_puts "Skipping dossier #{dossier.id} (not en instruction)\n"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
MassProcessProcedure8670.new.run
|
||||||
|
end
|
||||||
|
end
|
|
@ -136,7 +136,7 @@ describe API::V1::DossiersController do
|
||||||
context 'when dossier exists and belongs to procedure' do
|
context 'when dossier exists and belongs to procedure' do
|
||||||
let(:procedure_id) { procedure.id }
|
let(:procedure_id) { procedure.id }
|
||||||
let(:date_creation) { Time.zone.local(2008, 9, 1, 10, 5, 0) }
|
let(:date_creation) { Time.zone.local(2008, 9, 1, 10, 5, 0) }
|
||||||
let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure, motivation: "Motivation") } }
|
let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, :en_construction, procedure: procedure, motivation: "Motivation") } }
|
||||||
let(:dossier_id) { dossier.id }
|
let(:dossier_id) { dossier.id }
|
||||||
let(:body) { JSON.parse(retour.body, symbolize_names: true) }
|
let(:body) { JSON.parse(retour.body, symbolize_names: true) }
|
||||||
let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs] }
|
let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs] }
|
||||||
|
@ -147,7 +147,7 @@ describe API::V1::DossiersController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(subject[:id]).to eq(dossier.id) }
|
it { expect(subject[:id]).to eq(dossier.id) }
|
||||||
it { expect(subject[:state]).to eq(dossier.state) }
|
it { expect(subject[:state]).to eq('initiated') }
|
||||||
it { expect(subject[:created_at]).to eq('2008-09-01T08:05:00.000Z') }
|
it { expect(subject[:created_at]).to eq('2008-09-01T08:05:00.000Z') }
|
||||||
it { expect(subject[:updated_at]).to eq('2008-09-01T08:05:00.000Z') }
|
it { expect(subject[:updated_at]).to eq('2008-09-01T08:05:00.000Z') }
|
||||||
it { expect(subject[:archived]).to eq(dossier.archived) }
|
it { expect(subject[:archived]).to eq(dossier.archived) }
|
||||||
|
|
57
spec/controllers/users/confirmations_controller_spec.rb
Normal file
57
spec/controllers/users/confirmations_controller_spec.rb
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Users::ConfirmationsController, type: :controller do
|
||||||
|
let!(:user) { create(:user, :unconfirmed) }
|
||||||
|
let(:confirmation_token) { user.confirmation_token }
|
||||||
|
|
||||||
|
before do
|
||||||
|
@request.env["devise.mapping"] = Devise.mappings[:user]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#show' do
|
||||||
|
context 'when confirming within the auto-sign-in delay' do
|
||||||
|
before do
|
||||||
|
Timecop.travel(1.hour.from_now) {
|
||||||
|
get :show, params: { confirmation_token: confirmation_token }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'confirms the user' do
|
||||||
|
expect(user.reload).to be_confirmed
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'signs in the user after confirming its token' do
|
||||||
|
expect(controller.current_user).to eq(user)
|
||||||
|
expect(controller.current_gestionnaire).to be(nil)
|
||||||
|
expect(controller.current_administrateur).to be(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects the user to the root page' do
|
||||||
|
# NB: the root page may redirect the user again to the stored procedure path
|
||||||
|
expect(controller).to redirect_to(root_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the auto-sign-in delay has expired' do
|
||||||
|
before do
|
||||||
|
Timecop.travel(3.hours.from_now) {
|
||||||
|
get :show, params: { confirmation_token: confirmation_token }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'confirms the user' do
|
||||||
|
expect(user.reload).to be_confirmed
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'doesn’t sign in the user' do
|
||||||
|
expect(subject.current_user).to be(nil)
|
||||||
|
expect(subject.current_gestionnaire).to be(nil)
|
||||||
|
expect(subject.current_administrateur).to be(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects the user to the sign-in path' do
|
||||||
|
expect(subject).to redirect_to(new_user_session_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -18,38 +18,4 @@ describe DossierDecorator do
|
||||||
subject { super().last_update }
|
subject { super().last_update }
|
||||||
it { is_expected.to eq('24/12/2015 14:10') }
|
it { is_expected.to eq('24/12/2015 14:10') }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'state_fr' do
|
|
||||||
subject{ super().display_state }
|
|
||||||
|
|
||||||
it 'brouillon is brouillon' do
|
|
||||||
dossier.brouillon!
|
|
||||||
expect(subject).to eq('Brouillon')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'en_construction is En construction' do
|
|
||||||
dossier.en_construction!
|
|
||||||
expect(subject).to eq('En construction')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'accepte is traité' do
|
|
||||||
dossier.accepte!
|
|
||||||
expect(subject).to eq('Accepté')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'en_instruction is reçu' do
|
|
||||||
dossier.en_instruction!
|
|
||||||
expect(subject).to eq('En instruction')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'sans_suite is traité' do
|
|
||||||
dossier.sans_suite!
|
|
||||||
expect(subject).to eq('Sans suite')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'refuse is traité' do
|
|
||||||
dossier.refuse!
|
|
||||||
expect(subject).to eq('Refusé')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,5 +4,9 @@ FactoryBot.define do
|
||||||
email { generate(:user_email) }
|
email { generate(:user_email) }
|
||||||
password { 'password' }
|
password { 'password' }
|
||||||
confirmed_at { Time.zone.now }
|
confirmed_at { Time.zone.now }
|
||||||
|
|
||||||
|
trait :unconfirmed do
|
||||||
|
confirmed_at { nil }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,9 +73,6 @@ feature 'The gestionnaire part' do
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'A gestionnaire can use avis' do
|
scenario 'A gestionnaire can use avis' do
|
||||||
ActionMailer::Base.deliveries = []
|
|
||||||
ActiveJob::Base.queue_adapter = :test
|
|
||||||
|
|
||||||
log_in(gestionnaire.email, password)
|
log_in(gestionnaire.email, password)
|
||||||
|
|
||||||
click_on procedure.libelle
|
click_on procedure.libelle
|
||||||
|
|
|
@ -32,21 +32,17 @@ feature 'Invitations' do
|
||||||
scenario 'an invited user can register using the registration link sent in the invitation email' do
|
scenario 'an invited user can register using the registration link sent in the invitation email' do
|
||||||
# Click the invitation link
|
# Click the invitation link
|
||||||
visit users_dossiers_invite_path(invite.id, params: { email: invite.email })
|
visit users_dossiers_invite_path(invite.id, params: { email: invite.email })
|
||||||
|
|
||||||
# Create the account
|
|
||||||
expect(page).to have_current_path(new_user_registration_path, ignore_query: true)
|
expect(page).to have_current_path(new_user_registration_path, ignore_query: true)
|
||||||
expect(page).to have_field('user_email', with: invite.email)
|
expect(page).to have_field('user_email', with: invite.email)
|
||||||
fill_in 'user_password', with: user_password
|
|
||||||
click_on 'Créer un compte'
|
|
||||||
|
|
||||||
|
# Create the account
|
||||||
|
sign_up_with invite.email, user_password
|
||||||
expect(page).to have_content("lien d'activation")
|
expect(page).to have_content("lien d'activation")
|
||||||
|
|
||||||
# Confirm the email
|
# Confirm the account
|
||||||
user = User.find_by(email: invite.email)
|
# (The user should be redirected to the dossier they was invited on)
|
||||||
visit Rails.application.routes.url_helpers.user_confirmation_path(confirmation_token: user.confirmation_token)
|
click_confirmation_link_for invite.email
|
||||||
submit_login_form(user.email, user_password)
|
expect(page).to have_content('Votre compte a été activé')
|
||||||
|
|
||||||
# The user should be redirected to the dossier they was invited on
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -102,16 +98,10 @@ feature 'Invitations' do
|
||||||
def log_in(user)
|
def log_in(user)
|
||||||
visit '/'
|
visit '/'
|
||||||
click_on 'Connexion'
|
click_on 'Connexion'
|
||||||
submit_login_form(user.email, user.password)
|
sign_in_with(user.email, user.password)
|
||||||
expect(page).to have_current_path(dossiers_path)
|
expect(page).to have_current_path(dossiers_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def submit_login_form(email, password)
|
|
||||||
fill_in 'user_email', with: email
|
|
||||||
fill_in 'user_password', with: password
|
|
||||||
click_on 'Se connecter'
|
|
||||||
end
|
|
||||||
|
|
||||||
def navigate_to_brouillon(dossier)
|
def navigate_to_brouillon(dossier)
|
||||||
expect(page).to have_current_path(dossiers_path)
|
expect(page).to have_current_path(dossiers_path)
|
||||||
click_on(dossier.id)
|
click_on(dossier.id)
|
||||||
|
@ -127,7 +117,7 @@ feature 'Invitations' do
|
||||||
def navigate_to_invited_dossier(invite)
|
def navigate_to_invited_dossier(invite)
|
||||||
visit users_dossiers_invite_path(invite)
|
visit users_dossiers_invite_path(invite)
|
||||||
expect(page).to have_current_path(new_user_session_path)
|
expect(page).to have_current_path(new_user_session_path)
|
||||||
submit_login_form(invited_user.email, invited_user.password)
|
sign_in_with(invited_user.email, invited_user.password)
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_invite_to(invited_email)
|
def send_invite_to(invited_email)
|
||||||
|
|
36
spec/features/sessions/sign_up_spec.rb
Normal file
36
spec/features/sessions/sign_up_spec.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature 'Signin up:' do
|
||||||
|
scenario 'a new user can sign-up' do
|
||||||
|
visit root_path
|
||||||
|
click_on 'Connexion'
|
||||||
|
click_on 'Créer un compte'
|
||||||
|
|
||||||
|
sign_up_with 'testuser@exemple.fr'
|
||||||
|
expect(page).to have_content "Nous vous avons envoyé un email contenant un lien d'activation"
|
||||||
|
|
||||||
|
click_confirmation_link_for 'testuser@exemple.fr'
|
||||||
|
expect(page).to have_content 'Votre compte a été activé'
|
||||||
|
expect(page).to have_current_path dossiers_path
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when visiting a procedure' do
|
||||||
|
let(:procedure) { create :simple_procedure }
|
||||||
|
|
||||||
|
before do
|
||||||
|
visit commencer_path(path: procedure.path)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'a new user can sign-up and fill the procedure' do
|
||||||
|
expect(page).to have_current_path new_user_session_path
|
||||||
|
click_on 'Créer un compte'
|
||||||
|
|
||||||
|
sign_up_with 'testuser@exemple.fr'
|
||||||
|
expect(page).to have_content "Nous vous avons envoyé un email contenant un lien d'activation"
|
||||||
|
|
||||||
|
click_confirmation_link_for 'testuser@exemple.fr'
|
||||||
|
expect(page).to have_content 'Votre compte a été activé'
|
||||||
|
expect(page).to have_content procedure.libelle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -96,4 +96,108 @@ RSpec.describe DossierHelper, type: :helper do
|
||||||
it_behaves_like "returns false"
|
it_behaves_like "returns false"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.dossier_display_state' do
|
||||||
|
let(:dossier) { create(:dossier) }
|
||||||
|
|
||||||
|
subject { dossier_display_state(dossier) }
|
||||||
|
|
||||||
|
it 'brouillon is brouillon' do
|
||||||
|
dossier.brouillon!
|
||||||
|
expect(subject).to eq('Brouillon')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en_construction is En construction' do
|
||||||
|
dossier.en_construction!
|
||||||
|
expect(subject).to eq('En construction')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'accepte is traité' do
|
||||||
|
dossier.accepte!
|
||||||
|
expect(subject).to eq('Accepté')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en_instruction is reçu' do
|
||||||
|
dossier.en_instruction!
|
||||||
|
expect(subject).to eq('En instruction')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sans_suite is traité' do
|
||||||
|
dossier.sans_suite!
|
||||||
|
expect(subject).to eq('Sans suite')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'refuse is traité' do
|
||||||
|
dossier.refuse!
|
||||||
|
expect(subject).to eq('Refusé')
|
||||||
|
end
|
||||||
|
|
||||||
|
context "lower: true" do
|
||||||
|
subject { dossier_display_state(dossier, lower: true) }
|
||||||
|
|
||||||
|
it 'brouillon is brouillon' do
|
||||||
|
dossier.brouillon!
|
||||||
|
expect(subject).to eq('brouillon')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en_construction is En construction' do
|
||||||
|
dossier.en_construction!
|
||||||
|
expect(subject).to eq('en construction')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'accepte is traité' do
|
||||||
|
dossier.accepte!
|
||||||
|
expect(subject).to eq('accepté')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en_instruction is reçu' do
|
||||||
|
dossier.en_instruction!
|
||||||
|
expect(subject).to eq('en instruction')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sans_suite is traité' do
|
||||||
|
dossier.sans_suite!
|
||||||
|
expect(subject).to eq('sans suite')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'refuse is traité' do
|
||||||
|
dossier.refuse!
|
||||||
|
expect(subject).to eq('refusé')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.dossier_legacy_state' do
|
||||||
|
subject { dossier_legacy_state(dossier) }
|
||||||
|
|
||||||
|
context 'when the dossier is en instruction' do
|
||||||
|
let(:dossier) { create(:dossier) }
|
||||||
|
|
||||||
|
it { is_expected.to eq('brouillon') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier is en instruction' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction) }
|
||||||
|
|
||||||
|
it { is_expected.to eq('received') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier is accepte' do
|
||||||
|
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:accepte)) }
|
||||||
|
|
||||||
|
it { is_expected.to eq('closed') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier is refuse' do
|
||||||
|
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:refuse)) }
|
||||||
|
|
||||||
|
it { is_expected.to eq('refused') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier is sans_suite' do
|
||||||
|
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:sans_suite)) }
|
||||||
|
|
||||||
|
it { is_expected.to eq('without_continuation') }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe TypeDeChampHelper, type: :helper do
|
|
||||||
describe ".tdc_options" do
|
|
||||||
let(:pj_option) { ["Pièce justificative", TypeDeChamp.type_champs.fetch(:piece_justificative)] }
|
|
||||||
|
|
||||||
subject { tdc_options }
|
|
||||||
|
|
||||||
context "when the champ_pj is enabled" do
|
|
||||||
before do
|
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:champ_pj, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
it { is_expected.to include(pj_option) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when the champ_pj is disabled" do
|
|
||||||
before do
|
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:champ_pj, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it { is_expected.not_to include(pj_option) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -600,10 +600,6 @@ describe Dossier do
|
||||||
let(:procedure) { create(:procedure) }
|
let(:procedure) { create(:procedure) }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
before do
|
|
||||||
ActionMailer::Base.deliveries.clear
|
|
||||||
end
|
|
||||||
|
|
||||||
it "send an email when the dossier is created for the very first time" do
|
it "send an email when the dossier is created for the very first time" do
|
||||||
dossier = nil
|
dossier = nil
|
||||||
ActiveJob::Base.queue_adapter = :test
|
ActiveJob::Base.queue_adapter = :test
|
||||||
|
@ -1004,32 +1000,4 @@ describe Dossier do
|
||||||
it { expect(long_expired_dossier).to be_retention_expired }
|
it { expect(long_expired_dossier).to be_retention_expired }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'old_state_value' do
|
|
||||||
subject { dossier.old_state_value }
|
|
||||||
|
|
||||||
context 'when the dossier is en instruction' do
|
|
||||||
let(:dossier) { create(:dossier, :en_instruction) }
|
|
||||||
|
|
||||||
it { is_expected.to eq('received') }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the dossier is accepte' do
|
|
||||||
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:accepte)) }
|
|
||||||
|
|
||||||
it { is_expected.to eq('closed') }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the dossier is refuse' do
|
|
||||||
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:refuse)) }
|
|
||||||
|
|
||||||
it { is_expected.to eq('refused') }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the dossier is sans_suite' do
|
|
||||||
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:sans_suite)) }
|
|
||||||
|
|
||||||
it { is_expected.to eq('without_continuation') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,12 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe TypesDeChampService do
|
describe TypesDeChampService do
|
||||||
let(:params) { ActionController::Parameters.new({ procedure: { types_de_champ_attributes: types_de_champ_attributes } }) }
|
let(:params) { ActionController::Parameters.new({ procedure: { types_de_champ_attributes: types_de_champ_attributes } }) }
|
||||||
|
let(:procedure) { create(:procedure) }
|
||||||
|
let(:service) { TypesDeChampService.new(procedure) }
|
||||||
|
|
||||||
let(:result) { TypesDeChampService.create_update_procedure_params(params) }
|
describe 'create_update_procedure_params' do
|
||||||
|
let(:result) { service.create_update_procedure_params(params) }
|
||||||
|
|
||||||
describe 'self.create_update_procedure_params' do
|
|
||||||
describe 'the drop down list attributes' do
|
describe 'the drop down list attributes' do
|
||||||
let(:types_de_champ_attributes) do
|
let(:types_de_champ_attributes) do
|
||||||
{
|
{
|
||||||
|
@ -99,4 +101,26 @@ describe TypesDeChampService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe ".options" do
|
||||||
|
let(:pj_option) { ["Pièce justificative", TypeDeChamp.type_champs.fetch(:piece_justificative)] }
|
||||||
|
|
||||||
|
subject { service.options }
|
||||||
|
|
||||||
|
context "when the champ_pj is enabled" do
|
||||||
|
before do
|
||||||
|
Flipflop::FeatureSet.current.test!.switch!(:champ_pj, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to include(pj_option) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the champ_pj is disabled" do
|
||||||
|
before do
|
||||||
|
Flipflop::FeatureSet.current.test!.switch!(:champ_pj, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.not_to include(pj_option) }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,7 @@ require File.expand_path('../config/environment', __dir__)
|
||||||
require 'rspec/rails'
|
require 'rspec/rails'
|
||||||
require 'capybara/rspec'
|
require 'capybara/rspec'
|
||||||
require 'capybara-screenshot/rspec'
|
require 'capybara-screenshot/rspec'
|
||||||
|
require 'capybara/email/rspec'
|
||||||
require 'database_cleaner'
|
require 'database_cleaner'
|
||||||
require 'webmock/rspec'
|
require 'webmock/rspec'
|
||||||
require 'shoulda-matchers'
|
require 'shoulda-matchers'
|
||||||
|
@ -137,6 +138,8 @@ RSpec.configure do |config|
|
||||||
|
|
||||||
Typhoeus::Expectation.clear
|
Typhoeus::Expectation.clear
|
||||||
|
|
||||||
|
ActionMailer::Base.deliveries.clear
|
||||||
|
|
||||||
if Flipflop.remote_storage?
|
if Flipflop.remote_storage?
|
||||||
VCR.use_cassette("ovh_storage_init") do
|
VCR.use_cassette("ovh_storage_init") do
|
||||||
CarrierWave.configure do |config|
|
CarrierWave.configure do |config|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
module FeatureHelpers
|
module FeatureHelpers
|
||||||
|
include ActiveJob::TestHelper
|
||||||
|
|
||||||
def login_admin
|
def login_admin
|
||||||
user = create :user
|
user = create :user
|
||||||
login_as user, scope: :user
|
login_as user, scope: :user
|
||||||
|
@ -14,6 +16,28 @@ module FeatureHelpers
|
||||||
dossier = FactoryBot.create(:dossier)
|
dossier = FactoryBot.create(:dossier)
|
||||||
dossier
|
dossier
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sign_in_with(email, password)
|
||||||
|
fill_in :user_email, with: email
|
||||||
|
fill_in :user_password, with: password
|
||||||
|
click_on 'Se connecter'
|
||||||
|
end
|
||||||
|
|
||||||
|
def sign_up_with(email, password = 'testpassword')
|
||||||
|
fill_in :user_email, with: email
|
||||||
|
fill_in :user_password, with: password
|
||||||
|
|
||||||
|
perform_enqueued_jobs do
|
||||||
|
click_button 'Créer un compte'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def click_confirmation_link_for(email)
|
||||||
|
confirmation_email = open_email(email)
|
||||||
|
token_params = confirmation_email.body.match(/confirmation_token=[^"]+/)
|
||||||
|
|
||||||
|
visit "/users/confirmation?#{token_params}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do
|
||||||
before do
|
before do
|
||||||
procedure.reload
|
procedure.reload
|
||||||
assign(:procedure, procedure)
|
assign(:procedure, procedure)
|
||||||
assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(false, procedure))
|
assign(:type_de_champ_service, TypesDeChampService.new(procedure))
|
||||||
render
|
render
|
||||||
end
|
end
|
||||||
it 'sorts by order place' do
|
it 'sorts by order place' do
|
||||||
|
@ -26,7 +26,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do
|
||||||
subject do
|
subject do
|
||||||
procedure.reload
|
procedure.reload
|
||||||
assign(:procedure, procedure)
|
assign(:procedure, procedure)
|
||||||
assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(false, procedure))
|
assign(:type_de_champ_service, TypesDeChampService.new(procedure))
|
||||||
render
|
render
|
||||||
rendered
|
rendered
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do
|
||||||
before do
|
before do
|
||||||
procedure.reload
|
procedure.reload
|
||||||
assign(:procedure, procedure)
|
assign(:procedure, procedure)
|
||||||
assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(true, procedure))
|
assign(:type_de_champ_service, TypesDeChampService.new(procedure, true))
|
||||||
render
|
render
|
||||||
end
|
end
|
||||||
it 'sorts by order place' do
|
it 'sorts by order place' do
|
||||||
|
@ -26,7 +26,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do
|
||||||
subject do
|
subject do
|
||||||
procedure.reload
|
procedure.reload
|
||||||
assign(:procedure, procedure)
|
assign(:procedure, procedure)
|
||||||
assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(true, procedure))
|
assign(:type_de_champ_service, TypesDeChampService.new(procedure, true))
|
||||||
render
|
render
|
||||||
rendered
|
rendered
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue