Merge branch 'dev'

This commit is contained in:
gregoirenovel 2018-10-03 11:08:13 +02:00
commit de95e6e22d
83 changed files with 490 additions and 196068 deletions

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="550.801" height="550.801" viewBox="0 0 550.801 550.801"><path d="M160.381 282.225c0-14.832-10.299-23.684-28.474-23.684-7.414 0-12.437.715-15.071 1.432V307.6c3.114.707 6.942.949 12.192.949 19.391 0 31.353-9.809 31.353-26.324zM272.875 259.019c-8.145 0-13.397.717-16.519 1.435v105.523c3.116.729 8.142.729 12.69.729 33.017.231 54.554-17.946 54.554-56.474.242-33.513-19.385-51.213-50.725-51.213z"/><path d="M488.426 197.019H475.2v-63.816c0-.398-.063-.799-.116-1.202-.021-2.534-.827-5.023-2.562-6.995L366.325 3.694c-.032-.031-.063-.042-.085-.076-.633-.707-1.371-1.295-2.151-1.804a9.495 9.495 0 0 0-.706-.419 11.131 11.131 0 0 0-2.131-.896c-.2-.056-.38-.138-.58-.19A10.774 10.774 0 0 0 358.193 0H97.2C85.282 0 75.6 9.693 75.6 21.601v175.413H62.377c-17.049 0-30.873 13.818-30.873 30.873v160.545c0 17.043 13.824 30.87 30.873 30.87h13.224V529.2c0 11.907 9.682 21.601 21.6 21.601h356.4c11.907 0 21.6-9.693 21.6-21.601V419.302h13.226c17.044 0 30.871-13.827 30.871-30.87v-160.54c-.001-17.054-13.828-30.873-30.872-30.873zM97.2 21.605h250.193v110.513c0 5.967 4.841 10.8 10.8 10.8H453.6v54.108H97.2V21.605zm265.159 287.418c0 30.876-11.243 52.165-26.82 65.333-16.971 14.117-42.82 20.814-74.396 20.814-18.9 0-32.297-1.197-41.401-2.389V234.365c13.399-2.149 30.878-3.346 49.304-3.346 30.612 0 50.478 5.508 66.039 17.226 16.743 12.445 27.274 32.302 27.274 60.778zM80.7 393.499V234.365c11.241-1.904 27.042-3.346 49.296-3.346 22.491 0 38.527 4.308 49.291 12.928 10.292 8.131 17.215 21.534 17.215 37.328 0 15.799-5.25 29.198-14.829 38.285-12.442 11.728-30.865 16.996-52.407 16.996-4.778 0-9.1-.243-12.435-.723v57.67H80.7v-.004zm372.901 129.854H97.2V419.302h356.4v104.051zm31.297-261.226h-61.989v36.851h57.913v29.674h-57.913V393.5h-36.593V232.216h98.582v29.911z"/></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,27 +1,4 @@
$(document) $(document).on('turbolinks:load', handle_siret_form_errors);
.on('turbolinks:load', the_terms)
.on('turbolinks:load', handle_siret_form_errors);
function the_terms() {
var the_terms = $("#dossier_autorisation_donnees");
if (the_terms.length == 0)
return;
check_value(the_terms);
the_terms.click(function () {
check_value(the_terms);
});
function check_value(the_terms) {
if (the_terms.is(":checked")) {
$("#etape_suivante").removeAttr("disabled");
} else {
$("#etape_suivante").attr("disabled", "disabled");
}
}
}
function error_form_siret(invalid_siret) { function error_form_siret(invalid_siret) {
setTimeout(function () { setTimeout(function () {

View file

@ -21,9 +21,7 @@
// = require carte // = require carte
// = require custom_mails // = require custom_mails
// = require default_data_block // = require default_data_block
// = require description
// = require direct_uploads // = require direct_uploads
// = require dossier_show
// = require dossiers // = require dossiers
// = require etapes // = require etapes
// = require france_connect_particulier // = require france_connect_particulier
@ -35,7 +33,6 @@
// = require pj_modal // = require pj_modal
// = require print // = require print
// = require procedure // = require procedure
// = require recapitulatif
// = require search // = require search
// = require siret // = require siret
// = require outdated_browser_banner // = require outdated_browser_banner
@ -43,7 +40,6 @@
// = require autocomplete // = require autocomplete
// = require users // = require users
// = require attestation_template_edit // = require attestation_template_edit
// = require attestation_recapitulatif
// = require_self // = require_self
// = require leaflet // = require leaflet

View file

@ -1,31 +0,0 @@
#attestation-recapitulatif {
margin-top: 40px;
.details {
padding: 15px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #FFFFFF;
.left {
position: relative;
padding-left: 30px;
img {
position: absolute;
left: 0px;
top: 15px;
}
.title {
font-weight: bold;
margin: 0;
}
.delivery {
color: #999999;
}
}
}
}

View file

@ -1,147 +0,0 @@
@import "bootstrap";
#description-page #liste-champs {
.default-data-block {
.show-block {
width: 90%;
.body {
padding: 15px;
}
}
}
h4 {
padding-top: 35px;
margin: 0;
}
}
.page-header {
border-bottom: 1px solid #CCCCCC !important;
}
.input-error {
color: #8B0000 !important;
border-color: #8B0000 !important;
}
.type-champ-text {
@extend .col-md-6;
@extend .col-lg-6;
input[type='text'] {
width: 100%;
}
}
.type-champ-header-section {
@extend .col-md-12;
@extend .col-lg-12;
}
.type-champ-address {
@extend .col-md-6;
@extend .col-lg-6;
.algolia-autocomplete {
width: 100%;
input {
width: 100%;
display: block !important;
}
}
.aa-dropdown-menu {
width: 100%;
}
}
.type-champ-email {
@extend .col-md-4;
@extend .col-lg-4;
input[type='email'] {
width: 100%;
}
}
.type-champ-drop-down-list,
.type-champ-regions,
.type-champ-departements,
.type-champ-pays {
@extend .col-md-4;
@extend .col-lg-4;
}
.type-champ-civilite {
@extend .col-md-3;
@extend .col-lg-3;
}
.type-champ-yes-no {
@extend .col-md-3;
@extend .col-lg-3;
}
.type-champ-phone {
@extend .col-md-2;
@extend .col-lg-2;
input[type='phone'] {
width: 100%;
}
}
.datepicker-switch {
color: #0086B3;
text-decoration: underline;
}
.type-champ-textarea {
@extend .col-md-8;
@extend .col-lg-8;
textarea.form-control {
width: 100%;
height: 133px;
}
}
.type-champ-number {
@extend .col-md-3;
@extend .col-lg-3;
input[type='number'] {
width: 100%;
}
}
.type-champ-date {
@extend .col-md-2;
@extend .col-lg-2;
input[type='date'] {
width: 160px;
}
}
.type-champ-datetime {
@extend .col-md-5;
@extend .col-lg-5;
input[type='datetime'] {
width: 160px;
}
}
.piece-description {
display: block;
margin-top: 5px;
margin-bottom: 10px;
color: #737373;
font-weight: normal;
}

View file

@ -1,207 +0,0 @@
#users-recapitulatif-dossier-show {
#messages {
.last-commentaire {
display: block;
background-color: #FFFFFF;
.content,
.new-action {
margin-bottom: 20px;
}
}
.body {
.commentaires {
max-height: 350px;
overflow-y: scroll;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.075) 0%, rgba(219, 219, 219, 0) 50%, rgba(250, 251, 253, 0.18) 51%, #FFFFFF 100%);
}
.no-commentaires {
text-align: center;
font-size: 18px;
padding-top: 20px;
}
}
.last-commentaire,
.commentaire {
padding: 20px 0 0 20px;
.comment-header {
font-family: Arial;
font-size: 14px;
font-weight: bold;
line-height: 16px;
color: #000000;
margin-bottom: 10px;
}
.file {
padding-right: 70px;
text-align: center;
margin-bottom: 20px;
.link {
span {
width: 100%;
font-size: 40px;
}
}
}
}
.split-hr {
margin: 20px 20px 0 20px;
border-bottom: 1px solid #979797;
}
#new-commentaire {
padding: 15px;
}
}
.infos {
.split-row {
margin: 0 0 20px 0;
}
.entreprise-info {
font-size: 14px;
}
.entreprise-label {
font-weight: bold;
text-align: end;
}
}
#private-fields {
.text-primary {
color: #337AB7;
}
}
#pieces-jointes {
.piece-row {
margin: 20px;
.piece-label {
text-align: right;
font-weight: bold;
}
}
.modal-title {
color: #000000;
}
}
#carto {
#map {
margin-bottom: 20px;
height: 350px;
}
}
#dossier,
#pieces-jointes,
.infos,
#carto,
#private-fields {
.body {
padding: 20px 20px 0 20px;
color: #000000;
.libelle-procedure {
font-style: italic;
padding: 10px;
}
.depositaire-label {
font-weight: bold;
text-align: end;
}
.btn-action {
border: none;
margin: 20px 0 40px 0;
}
.btn-action:hover {
color: #EEEEEE;
}
.action {
margin: 50px 0 0 15px;
}
.action,
.btn-action {
background-color: #E45B51;
text-align: center;
cursor: pointer;
color: #FFFFFF;
width: 253px;
height: 40px;
line-height: 40px;
font-family: Arial;
font-size: 16px;
font-weight: bold;
text-decoration: none;
a:hover {
color: #EEEEEE;
}
}
.historique {
color: #000000;
margin-left: 20px;
}
.comments {
margin-right: -10px;
}
.comments-off {
margin-right: -35px;
}
.dossier-title {
font-size: 16px;
min-height: 40px;
text-align: center;
}
.split-hr {
border-bottom: 1px solid #979797;
height: 12px;
min-height: 10px;
}
.title-row {
margin: 20px 10px 10px 10px;
}
.margin-top-40 {
margin-top: 40px;
}
.margin-top-20 {
margin-top: 20px;
}
.margin-bot-40 {
margin-bottom: 40px;
}
}
#pieces-justificatives {
.piece-row {
margin: 0 0 0 0;
}
}
}
}

View file

@ -1,9 +0,0 @@
#upload-pj-modal {
text-align: left;
table {
width: 100% !important;
margin-left: 0 !important;
margin-bottom: 0;
}
}

View file

@ -32,7 +32,6 @@
.white-back, .white-back,
#users-siret-index, #users-siret-index,
#description-page,
#carto-page { #carto-page {
background-color: #FFFFFF; background-color: #FFFFFF;
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.5); box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.5);

View file

@ -1,29 +0,0 @@
class CommentairesController < ApplicationController
def create
@commentaire = Commentaire.new
if params[:champ_id]
@commentaire.champ = @commentaire.dossier.champs.find(params[:champ_id])
end
dossier_id = params['dossier_id']
@commentaire.email = current_user.email
@commentaire.dossier = current_user.dossiers.find_by(id: dossier_id) || current_user.invites.find_by!(dossier_id: dossier_id).dossier
@commentaire.file = params["file"]
@commentaire.body = params['texte_commentaire']
if @commentaire.save
flash.notice = "Votre message a été envoyé"
else
flash.alert = "Veuillez rédiger un message ou ajouter une pièce jointe (maximum 20 Mo)"
end
if current_user.email != @commentaire.dossier.user.email
invite = Invite.where(dossier: @commentaire.dossier, email: current_user.email).first
redirect_to url_for(controller: 'users/dossiers/invites', action: :show, id: invite.id)
else
redirect_to users_dossier_recapitulatif_path(params['dossier_id'])
end
end
end

View file

@ -0,0 +1,4 @@
module Manager
class ServicesController < Manager::ApplicationController
end
end

View file

@ -54,10 +54,8 @@ module NewUser
def update_identite def update_identite
@dossier = dossier @dossier = dossier
individual_updated = @dossier.individual.update(individual_params) if @dossier.individual.update(individual_params)
dossier_updated = @dossier.update(dossier_params) @dossier.update!(autorisation_donnees: true)
if individual_updated && dossier_updated
flash.notice = "Identité enregistrée" flash.notice = "Identité enregistrée"
if @dossier.procedure.module_api_carto.use_api_carto if @dossier.procedure.module_api_carto.use_api_carto
@ -66,7 +64,7 @@ module NewUser
redirect_to brouillon_dossier_path(@dossier) redirect_to brouillon_dossier_path(@dossier)
end end
else else
flash.now.alert = @dossier.errors.full_messages flash.now.alert = @dossier.individual.errors.full_messages
render :identite render :identite
end end
end end
@ -257,10 +255,6 @@ module NewUser
params.require(:individual).permit(:gender, :nom, :prenom, :birthdate) params.require(:individual).permit(:gender, :nom, :prenom, :birthdate)
end end
def dossier_params
params.require(:dossier).permit(:autorisation_donnees)
end
def commentaire_params def commentaire_params
params.require(:commentaire).permit(:body, :file) params.require(:commentaire).permit(:body, :file)
end end

View file

@ -1,3 +0,0 @@
class Users::CommentairesController < CommentairesController
before_action :authenticate_user!
end

View file

@ -1,30 +0,0 @@
class Users::DescriptionController < UsersController
def pieces_justificatives
invite = current_user.invite? params[:dossier_id]
if invite
@dossier ||= Dossier.find(params[:dossier_id])
end
@dossier ||= current_user_dossier
if (errors_upload = PiecesJustificativesService.upload!(@dossier, current_user, params)).present?
if flash.alert.nil?
flash.alert = errors_upload
else
flash.alert = [flash.alert] + errors_upload
end
else
if flash.alert.nil?
flash.notice = 'Nouveaux fichiers envoyés'
end
end
if invite
return redirect_to users_dossiers_invite_path(id: current_user.invites.find_by(dossier_id: @dossier.id).id)
end
redirect_to users_dossier_recapitulatif_path
end
end

View file

@ -1,3 +0,0 @@
class Users::Dossiers::CommentairesController < CommentairesController
before_action :authenticate_user!
end

View file

@ -132,22 +132,12 @@ class Users::DossiersController < UsersController
def update def update
@facade = facade params[:dossier][:id] @facade = facade params[:dossier][:id]
@facade.dossier.update!(autorisation_donnees: true)
if individual_errors.any? if @facade.dossier.procedure.module_api_carto.use_api_carto
flash.alert = individual_errors redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id)
redirect_to users_dossier_path(id: @facade.dossier.id)
else else
if !Dossier.find(@facade.dossier.id).update(update_params) redirect_to brouillon_dossier_path(@facade.dossier)
flash.alert = @facade.dossier.errors.full_messages
return redirect_to users_dossier_path(id: @facade.dossier.id)
end
if @facade.dossier.procedure.module_api_carto.use_api_carto
redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id)
else
redirect_to brouillon_dossier_path(@facade.dossier)
end
end end
end end
@ -181,20 +171,6 @@ class Users::DossiersController < UsersController
render '/dossiers/new_siret', formats: :js, locals: { invalid_siret: siret } render '/dossiers/new_siret', formats: :js, locals: { invalid_siret: siret }
end end
def update_params
params.require(:dossier).permit(:id, :autorisation_donnees)
end
def individual_errors
errors = []
if update_params[:autorisation_donnees] != "1"
errors << "La validation des conditions d'utilisation est obligatoire"
end
errors
end
def siret def siret
create_params[:siret] create_params[:siret]
end end

View file

@ -1,40 +0,0 @@
class Users::RecapitulatifController < UsersController
before_action only: [:show] do
authorized_routes? self.class
end
def show
redirect_to dossier_url(current_user_dossier)
end
def initiate
create_dossier_facade
@facade.dossier.en_construction!
flash.notice = 'Dossier soumis avec succès.'
redirect_to users_dossier_recapitulatif_path
end
def self.route_authorization
{
states: [
Dossier.states.fetch(:en_construction),
Dossier.states.fetch(:en_instruction),
Dossier.states.fetch(:sans_suite),
Dossier.states.fetch(:accepte),
Dossier.states.fetch(:refuse)
]
}
end
private
def create_dossier_facade
@facade = DossierFacades.new current_user_dossier.id, current_user.email
rescue ActiveRecord::RecordNotFound
flash.alert = t('errors.messages.dossier_not_found')
redirect_to url_for(root_path)
end
end

View file

@ -28,6 +28,12 @@ class ProcedureDashboard < Administrate::BaseDashboard
hidden_at: Field::DateTime, hidden_at: Field::DateTime,
archived_at: Field::DateTime, archived_at: Field::DateTime,
whitelisted_at: Field::DateTime, whitelisted_at: Field::DateTime,
service: Field::BelongsTo,
initiated_mail_template: MailTemplateField,
received_mail_template: MailTemplateField,
closed_mail_template: MailTemplateField,
refused_mail_template: MailTemplateField,
without_continuation_mail_template: MailTemplateField,
}.freeze }.freeze
# COLLECTION_ATTRIBUTES # COLLECTION_ATTRIBUTES
@ -54,6 +60,7 @@ class ProcedureDashboard < Administrate::BaseDashboard
:description, :description,
:organisation, :organisation,
:direction, :direction,
:service,
:created_at, :created_at,
:updated_at, :updated_at,
:published_at, :published_at,
@ -65,7 +72,12 @@ class ProcedureDashboard < Administrate::BaseDashboard
:for_individual, :for_individual,
:individual_with_siret, :individual_with_siret,
:auto_archive_on, :auto_archive_on,
:gestionnaires :gestionnaires,
:initiated_mail_template,
:received_mail_template,
:closed_mail_template,
:refused_mail_template,
:without_continuation_mail_template,
].freeze ].freeze
# FORM_ATTRIBUTES # FORM_ATTRIBUTES

View file

@ -0,0 +1,63 @@
require "administrate/base_dashboard"
class ServiceDashboard < Administrate::BaseDashboard
# ATTRIBUTE_TYPES
# a hash that describes the type of each of the model's fields.
#
# Each different type represents an Administrate::Field object,
# which determines how the attribute is displayed
# on pages throughout the dashboard.
ATTRIBUTE_TYPES = {
id: Field::Number,
type_organisme: Field::String,
nom: Field::String,
created_at: Field::DateTime,
updated_at: Field::DateTime,
administrateur: Field::BelongsTo,
organisme: Field::String,
email: Field::String,
telephone: Field::String,
horaires: Field::String,
adresse: Field::String,
siret: Field::String,
}.freeze
# COLLECTION_ATTRIBUTES
# an array of attributes that will be displayed on the model's index page.
#
# By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [
:nom,
:type_organisme,
].freeze
# SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [
:id,
:type_organisme,
:nom,
:created_at,
:updated_at,
:administrateur,
:organisme,
:email,
:telephone,
:horaires,
:adresse,
:siret,
].freeze
# FORM_ATTRIBUTES
# an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [].freeze
# Overwrite this method to customize how users are displayed
# across all pages of the admin dashboard.
#
def display_resource(service)
service.nom
end
end

View file

@ -1,7 +0,0 @@
class CommentaireDecorator < Draper::Decorator
delegate_all
def created_at_fr
created_at.localtime.strftime('%d/%m/%Y - %H:%M')
end
end

View file

@ -0,0 +1,7 @@
require "administrate/field/base"
class MailTemplateField < Administrate::Field::Base
def name
data.class::DISPLAYED_NAME
end
end

View file

@ -36,8 +36,6 @@ class Dossier < ApplicationRecord
accepts_nested_attributes_for :champs accepts_nested_attributes_for :champs
accepts_nested_attributes_for :champs_private accepts_nested_attributes_for :champs_private
validates :autorisation_donnees, acceptance: { message: 'doit être coché' }, allow_nil: false, on: :update
default_scope { where(hidden_at: nil) } default_scope { where(hidden_at: nil) }
scope :state_brouillon, -> { where(state: states.fetch(:brouillon)) } scope :state_brouillon, -> { where(state: states.fetch(:brouillon)) }
scope :state_not_brouillon, -> { where.not(state: states.fetch(:brouillon)) } scope :state_not_brouillon, -> { where.not(state: states.fetch(:brouillon)) }
@ -231,10 +229,6 @@ class Dossier < ApplicationRecord
DossierFieldService.get_value(self, table, column) DossierFieldService.get_value(self, table, column)
end end
def self.sanitize_for_order(order)
sanitize_sql_for_order(order)
end
def owner_name def owner_name
if etablissement.present? if etablissement.present?
etablissement.entreprise_raison_sociale etablissement.entreprise_raison_sociale

View file

@ -1,3 +1,45 @@
class ProcedurePresentation < ApplicationRecord class ProcedurePresentation < ApplicationRecord
belongs_to :assign_to belongs_to :assign_to
delegate :procedure, to: :assign_to
validate :check_allowed_displayed_fields
validate :check_allowed_sort_column
validate :check_allowed_filter_columns
def check_allowed_displayed_fields
displayed_fields.each do |field|
table = field['table']
column = field['column']
if !DossierFieldService.valid_column?(procedure, table, column)
errors.add(:filters, "#{table}.#{column} nest pas une colonne permise")
end
end
end
def check_allowed_sort_column
table = sort['table']
column = sort['column']
if !valid_sort_column?(procedure, table, column)
errors.add(:sort, "#{table}.#{column} nest pas une colonne permise")
end
end
def check_allowed_filter_columns
filters.each do |_, columns|
columns.each do |column|
table = column['table']
column = column['column']
if !DossierFieldService.valid_column?(procedure, table, column)
errors.add(:filters, "#{table}.#{column} nest pas une colonne permise")
end
end
end
end
private
def valid_sort_column?(procedure, table, column)
DossierFieldService.valid_column?(procedure, table, column) || (table == 'notifications' && column == 'notifications')
end
end end

View file

@ -1,4 +1,6 @@
class DossierFieldService class DossierFieldService
@@column_whitelist = {}
class << self class << self
def fields(procedure) def fields(procedure)
fields = [ fields = [
@ -44,6 +46,8 @@ class DossierFieldService
end end
def get_value(dossier, table, column) def get_value(dossier, table, column)
assert_valid_column(dossier.procedure, table, column)
case table case table
when 'self' when 'self'
dossier.send(column) dossier.send(column)
@ -60,9 +64,21 @@ class DossierFieldService
end end
end end
def assert_valid_column(procedure, table, column)
if !valid_column?(procedure, table, column)
raise "Invalid column #{table}.#{column}"
end
end
def valid_column?(procedure, table, column)
valid_columns_for_table(procedure, table).include?(column)
end
def filtered_ids(dossiers, filters) def filtered_ids(dossiers, filters)
filters.map do |filter| filters.map do |filter|
case filter['table'] table = filter['table']
column = sanitized_column(filter)
case table
when 'self' when 'self'
dossiers.where("? ILIKE ?", filter['column'], "%#{filter['value']}%") dossiers.where("? ILIKE ?", filter['column'], "%#{filter['value']}%")
@ -72,72 +88,97 @@ class DossierFieldService
.where("? ILIKE ?", "france_connect_informations.#{filter['column']}", "%#{filter['value']}%") .where("? ILIKE ?", "france_connect_informations.#{filter['column']}", "%#{filter['value']}%")
when 'type_de_champ', 'type_de_champ_private' when 'type_de_champ', 'type_de_champ_private'
relation = filter['table'] == 'type_de_champ' ? :champs : :champs_private relation = table == 'type_de_champ' ? :champs : :champs_private
dossiers dossiers
.includes(relation) .includes(relation)
.where("champs.type_de_champ_id = ?", filter['column'].to_i) .where("champs.type_de_champ_id = ?", filter['column'].to_i)
.where("champs.value ILIKE ?", "%#{filter['value']}%") .where("champs.value ILIKE ?", "%#{filter['value']}%")
when 'etablissement' when 'etablissement'
table = filter['table']
if filter['column'] == 'entreprise_date_creation' if filter['column'] == 'entreprise_date_creation'
date = filter['value'].to_date rescue nil date = filter['value'].to_date rescue nil
dossiers dossiers
.includes(table) .includes(table)
.where("#{table.pluralize}.#{filter['column']} = ?", date) .where("#{column} = ?", date)
else else
dossiers dossiers
.includes(table) .includes(table)
.where("#{table.pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%") .where("#{column} ILIKE ?", "%#{filter['value']}%")
end end
when 'user' when 'user'
dossiers dossiers
.includes(filter['table']) .includes(table)
.where("#{filter['table'].pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%") .where("#{column} ILIKE ?", "%#{filter['value']}%")
end.pluck(:id) end.pluck(:id)
end.reduce(:&) end.reduce(:&)
end end
def sorted_ids(dossiers, procedure_presentation, gestionnaire) def sorted_ids(dossiers, procedure_presentation, gestionnaire)
table = procedure_presentation.sort['table'] table = procedure_presentation.sort['table']
column = procedure_presentation.sort['column'] column = sanitized_column(procedure_presentation.sort)
order = procedure_presentation.sort['order'] order = procedure_presentation.sort['order']
includes = '' assert_valid_order(order)
where = ''
sorted_ids = nil
case table case table
when 'notifications' when 'notifications'
procedure = procedure_presentation.assign_to.procedure procedure = procedure_presentation.assign_to.procedure
dossiers_id_with_notification = gestionnaire.notifications_for_procedure(procedure) dossiers_id_with_notification = gestionnaire.notifications_for_procedure(procedure)
if order == 'desc' if order == 'desc'
sorted_ids = dossiers_id_with_notification + (dossiers.order('dossiers.updated_at desc').ids - dossiers_id_with_notification) return dossiers_id_with_notification +
(dossiers.order('dossiers.updated_at desc').ids - dossiers_id_with_notification)
else else
sorted_ids = (dossiers.order('dossiers.updated_at asc').ids - dossiers_id_with_notification) + dossiers_id_with_notification return (dossiers.order('dossiers.updated_at asc').ids - dossiers_id_with_notification) +
dossiers_id_with_notification
end end
when 'self' when 'self'
order = "dossiers.#{column} #{order}" return dossiers
.order("#{column} #{order}")
.pluck(:id)
when 'france_connect_information' when 'france_connect_information'
includes = { user: :france_connect_information } return dossiers
order = "france_connect_informations.#{column} #{order}" .includes(user: :france_connect_information)
.order("#{column} #{order}")
.pluck(:id)
when 'type_de_champ', 'type_de_champ_private' when 'type_de_champ', 'type_de_champ_private'
includes = table == 'type_de_champ' ? :champs : :champs_private return dossiers
where = "champs.type_de_champ_id = #{column.to_i}" .includes(table == 'type_de_champ' ? :champs : :champs_private)
order = "champs.value #{order}" .where("champs.type_de_champ_id = #{procedure_presentation.sort['column'].to_i}")
.order("champs.value #{order}")
.pluck(:id)
else else
includes = table return dossiers
order = "#{table.pluralize}.#{column} #{order}" .includes(table)
.order("#{column} #{order}")
.pluck(:id)
end end
if sorted_ids.nil?
sorted_ids = dossiers.includes(includes).where(where).order(Dossier.sanitize_for_order(order)).pluck(:id)
end
sorted_ids
end end
private private
def valid_columns_for_table(procedure, table)
if !@@column_whitelist.key?(procedure.id)
@@column_whitelist[procedure.id] = fields(procedure)
.group_by { |field| field['table'] }
.map { |table, fields| [table, Set.new(fields.map { |field| field['column'] }) ] }
.to_h
end
@@column_whitelist[procedure.id][table] || []
end
def sanitized_column(field)
table = field['table']
table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize)
column = ActiveRecord::Base.connection.quote_column_name(field['column'])
table + '.' + column
end
def assert_valid_order(order)
if !%w[asc desc].include?(order)
raise "Invalid order #{order}"
end
end
def field_hash(label, table, column) def field_hash(label, table, column)
{ {
'label' => label, 'label' => label,

View file

@ -1,17 +0,0 @@
- if dossier.attestation.present?
#attestation-recapitulatif.default-data-block
.row.show-block.clearfix
.header
.title
.carret-right
.carret-down
ATTESTATION
.details
.left
= image_tag('pdf.svg', width: '20px')
%p.title= dossier.attestation.title
%p.delivery Délivrée le #{l(dossier.attestation.created_at, format: '%d %B %Y')}
- if user_signed_in? && current_user == dossier.user
= link_to 'Télécharger', attestation_dossier_path(dossier), target: '_blank', class: 'btn btn-primary'
- else
= link_to 'Télécharger', attestation_gestionnaire_dossier_path(dossier.procedure, dossier), target: '_blank', class: 'btn btn-primary'

View file

@ -1,56 +0,0 @@
= render partial: 'dossiers/attestation', locals: { dossier: @facade.dossier }
= render partial: 'dossiers/messagerie', locals: { dossier_facade: @facade }
= render partial: 'dossiers/motivation', locals: { dossier_facade: @facade }
- if @facade.procedure.individual_with_siret
.default-data-block
.row.show-block.infos
.header
.col-xs-8.title-no-expanse
.carret-right
INFORMATIONS DU DEMANDEUR
- if [Dossier.states.fetch(:brouillon), Dossier.states.fetch(:en_construction)].include?(@facade.dossier.state)
%a#add_siret.action{ href: users_dossier_add_siret_path(dossier_id: @facade.dossier.id) }
.col-lg-4.col-md-4.col-sm-4.col-xs-4.action
Renseigner un SIRET
- if @facade.etablissement.present?
.default-data-block
.row.show-block.infos#infos_entreprise
.header
.col-xs-12.title
.carret-right
.carret-down
INFORMATIONS DU DEMANDEUR
.body.display-block-on-print
= render partial: '/dossiers/infos_entreprise'
.default-data-block.default_visible
.row.show-block.infos#infos-dossiers
.header
.col-xs-10.title
.carret-right
.carret-down
CONSTRUCTION DU DOSSIER
= render partial: '/dossiers/edit_dossier'
.body.display-block-on-print
= render partial: '/dossiers/infos_dossier'
- if @facade.dossier.procedure.module_api_carto.use_api_carto
.default-data-block.default_visible.no-page-break-inside
.row.show-block#carto
.header
.col-xs-10.title
.carret-right
.carret-down
CARTOGRAPHIE
= render partial: '/dossiers/edit_carto'
.body.display-block-on-print
%input#json_latlngs{ type: 'hidden', value: "#{@facade.dossier.json_latlngs}", name: 'json_latlngs' }
%input#quartier_prioritaires{ type: 'hidden', value: "#{@facade.dossier.quartier_prioritaires.to_json}" }
%input#cadastres{ type: 'hidden', value: "#{@facade.dossier.cadastres.to_json}" }
= render partial: '/users/carte/map', locals: { dossier: @facade.dossier }
= render partial: 'users/carte/init_carto', locals: { dossier: @facade.dossier }

View file

@ -1,5 +0,0 @@
- if !@facade.dossier.read_only?
- if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier))
%a#maj_carte.action{ href: "/users/dossiers/#{@facade.dossier.id}/carte" }
.col-lg-2.col-md-2.col-sm-2.col-xs-2.action
= 'MODIFIER'

View file

@ -1,5 +0,0 @@
- if !@facade.dossier.read_only?
- if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier))
= link_to brouillon_dossier_path(@facade.dossier), class: 'action', id: 'maj_infos' do
#edit-dossier.col-lg-2.col-md-2.col-sm-2.col-xs-2.action
= "MODIFIER"

View file

@ -1,11 +0,0 @@
- if !@facade.dossier.read_only?
- if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier))
- if @facade.dossier.types_de_piece_justificative.size > 0
.col-lg-4.col-md-4.col-sm-4.col-xs-4.action
%a#maj_pj.action{ "data-target" => "#upload-pj-modal",
"data-toggle" => "modal",
:type => "button",
style: 'margin-bottom: 15px; margin-top: -30px;' }
Modifier les documents
%br
= render partial: 'users/recapitulatif/modal_upload_pj'

View file

@ -1,146 +0,0 @@
.row
.col-xs-12
- if @facade.procedure.for_individual?
.row.title-row
.col-xs-4.split-hr
.col-xs-4.dossier-title= t('utils.depositaire')
.col-xs-4.split-hr
.row
.col-xs-6.depositaire-label Civilité
.col-xs-1.comments-off= "-"
.col-xs-5.depositaire-info= @facade.individual.gender
.row
.col-xs-6.depositaire-label Nom
.col-xs-1.comments-off= "-"
.col-xs-5.depositaire-info= @facade.individual.nom
.row
.col-xs-6.depositaire-label Prénom
.col-xs-1.comments-off= "-"
.col-xs-5.despositaire-info= @facade.individual.prenom
.row
.col-xs-6.depositaire-label Date de naissance
.col-xs-1.comments-off= "-"
.col-xs-4.depositaire-info= @facade.individual.birthdate&.strftime("%d/%m/%Y")
.row.margin-top-20
- if @facade.champs.present?
- @facade.champs.each do |champ|
- next if champ.type_champ == TypeDeChamp.type_champs.fetch(:explication)
- if champ.type_champ == TypeDeChamp.type_champs.fetch(:header_section)
.row.title-row.margin-top-40
.col-xs-3.split-hr
.col-xs-6.dossier-title= champ.libelle
.col-xs-3.split-hr
- else
.row
.col-xs-6.depositaire-label= champ.libelle
.col-xs-1.comments-off
= "-"
.col-xs-5.depositaire-info{ id: "champ-#{champ.id}-value" }
- if champ.decorate.value.present? || champ.piece_justificative_file.attached?
- if champ.type_champ == TypeDeChamp.type_champs.fetch(:dossier_link)
- dossier = Dossier.includes(:procedure).find_by(id: champ.decorate.value)
- if dossier
= link_to("Dossier #{dossier.id}", brouillon_dossier_path(dossier), target: '_blank')
%br
= sanitize(dossier.text_summary)
- else
Pas de dossier associé
- elsif champ.type_champ == TypeDeChamp.type_champs.fetch(:piece_justificative)
= render partial: "shared/champs/piece_justificative/pj_link", locals: { champ: champ, user_can_upload: true }
- elsif champ.type_champ == TypeDeChamp.type_champs.fetch(:textarea)
= simple_format(champ.decorate.value)
- elsif champ.type_champ == TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
= champ.for_display
- else
= sanitize(champ.decorate.value)
.row
- if @facade.dossier.types_de_piece_justificative.count > 0
.col-xs-12
.row.title-row
.col-xs-4.split-hr
.col-xs-4.dossier-title= t('utils.pieces')
.col-xs-4.split-hr
.col-xs-12#pieces-justificatives.margin-bot-40
.row
.col-xs-12
- @facade.types_de_pieces_justificatives.each do |type_de_piece_justificative|
.row.piece-row
.col-xs-12{ id: "piece_justificative_#{type_de_piece_justificative.id}" }
.row
.col-xs-6.depositaire-label= type_de_piece_justificative.libelle
.col-xs-1.comments-off= "-"
.col-xs-5.despositaire-info
- if type_de_piece_justificative.api_entreprise
%span.text-success Nous l'avons récupéré pour vous.
- elsif (@pj = @facade.dossier.retrieve_last_piece_justificative_by_type(type_de_piece_justificative.id)).present?
%a{ href: "#{@pj.content_url}", target: '_blank' } Consulter
%span{ style: 'margin-left: 12px;' }
\-
- if @facade.dossier.pieces_justificatives.where(type_de_piece_justificative_id: type_de_piece_justificative.id).count > 1
= link_to "", class: "historique", "data-toggle" => "modal", "data-target" => "#pj-modal", :type => "button", "data-modal_title" => 'formulaires', "data-modal_index" => "type_de_pj_#{type_de_piece_justificative.id}" do
%span.fa.fa-clock-o
- else
Pièce non fournie
- if !@facade.dossier.read_only?
- if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier))
- if @facade.dossier.types_de_piece_justificative.size > 0
.row
.col-xs-4
%a#maj_pj.action{ "data-target" => "#upload-pj-modal", "data-toggle" => "modal", :type => "button" }
.col-xs-4.action
Modifier les documents
%br
= render partial: 'users/recapitulatif/modal_upload_pj'
.col-xs-4
- if gestionnaire_signed_in?
#pj-modal.modal.fade{ "aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1" }
.modal-dialog.modal-lg{ :role => "document" }
.modal-content
.modal-header
%button.close{ "aria-label" => "Close", "data-dismiss" => "modal", :type => "button" }
%span{ "aria-hidden" => "true" } ×
%h4#myModalLabel.modal-title
Historique des
%span#pj-modal-title
.modal-body
%table.table
%thead
%th
Usager
%th
Date d'envoi
%th
Lien
%thead.tr-content#cerfa
- @facade.dossier.types_de_piece_justificative.each do |type_de_piece_justificative|
%tbody.tr-content{ id: "type_de_pj_#{type_de_piece_justificative.id}" }
- @facade.dossier.retrieve_all_piece_justificative_by_type(type_de_piece_justificative.id).each do |piece_justificative|
%tr
%td.col-md-6.col-sm-6.col-xs-6.col-lg-4
= piece_justificative.user.email
%td.col-md-6.col-sm-6.col-xs-6.col-lg-4
= piece_justificative.created_at
%td.col-md-6.col-sm-6.col-xs-6.col-lg-4
= link_to 'Récupérer', piece_justificative.content_url, { target: :blank }
.modal-footer
#modalCommentairesDossierParChamp.modal.fade{ "tabindex" => -1, "role" => "dialog" }
.modal-dialog{ "role" => "document" }
.modal-content
.modal-header
%button.close{ "data-dismiss" => "modal", "aria-label" => "Fermer" }
%span{ "aria-hidden" => true }
&times;
.modal-title
Messages
.modal-body
%p
Chargement des messages en cours...
.modal-footer
%button.btn.btn-primary{ "data-dismiss" => "modal" }
Fermer

View file

@ -1,29 +0,0 @@
#pieces-justificatives
.row
.col-xs-12
- @facade.dossier.types_de_piece_justificative.order('order_place ASC').each do |type_de_piece_justificative|
.row.piece-row
.col-xs-12{ id: "piece_justificative_#{type_de_piece_justificative.id}" }
.row
.col-xs-6= type_de_piece_justificative.libelle
.col-xs-6
- if type_de_piece_justificative.api_entreprise
%span.text-success Nous l'avons récupéré pour vous.
- elsif (@pj = @facade.dossier.retrieve_last_piece_justificative_by_type(type_de_piece_justificative.id)).present?
-# - if user_signed_in?
-# = 'Pièce fournie'
-# - elsif gestionnaire_signed_in?
%a{ href: "#{@pj.content_url}", target: '_blank' } Consulter
%span{ style: 'margin-left: 12px;' }
\-
%a.btn.fa.fa-timer{ style: 'color: black; padding-top: 0;',
"data-target" => "#pj-modal",
"data-toggle" => "modal",
:type => "button",
"data-modal_title" => type_de_piece_justificative.libelle,
"data-modal_index" => "type_de_pj_#{type_de_piece_justificative.id}" }
- else
= 'Pièce non fournie'
-# - if gestionnaire_signed_in?
= render partial: '/dossiers/modal_historique'

View file

@ -1,17 +0,0 @@
%h3 Personnes invitées à voir ce dossier
%br
.row
.col-xs-4
- if @facade.invites.size > 0
%ul
- @facade.invites.each do |invite|
%li
= invite.email
- else
Aucune personne invitée
.col-xs-3
= form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do
= text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation'
= submit_tag 'Ajouter', class: 'btn btn-success', id: 'send-invitation', data: { confirm: "Envoyer l'invitation ?" }

View file

@ -1,29 +0,0 @@
.default-data-block{ style: 'margin-top: 40px;' }
.row.show-block.clearfix#messages
.header
.col-xs-10.title
.carret-right
.carret-down
MESSAGERIE
.col-xs-2.count
= pluralize(@facade.commentaires.count, "message")
.alert.alert-info
Cette messagerie permet d'échanger entre le demandeur et le service instructeur.
.body.display-block-on-print
- if dossier_facade.commentaires.any?
.commentaires
= render partial: 'dossiers/commentaires/commentaire', collection: dossier_facade.commentaires.object.sort
.split-hr
#new-commentaire.hidden-print
= render partial: 'dossiers/commentaires/form', locals: { dossier_facade: @facade }
.last-commentaire.clearfix.hidden-print
- if last_comment = dossier_facade.commentaires.last
%div
DERNIER MESSAGE
= render partial: 'dossiers/commentaires/commentaire', object: last_comment
%button#open-message.new-action.btn.btn-danger
ENVOYER UN MESSAGE

View file

@ -1,11 +0,0 @@
- if Dossier::TERMINE.include?(@facade.dossier.state) && @facade.dossier.motivation.present?
.default-data-block.default_visible
.row.show-block.infos
.header
.col-xs-12.title
.carret-right
.carret-down
MOTIVATION
.body
.display-block-on-print
= @facade.dossier.motivation

View file

@ -1,6 +1,6 @@
<% if flash.empty? %> <% if flash.empty? %>
$('.row.etape.etape-2').hide(300, render_new_siret); $('.row.etape.etape-2').hide(300, render_new_siret);
$('.row.etape.etape-2').slideDown(400, the_terms); $('.row.etape.etape-2').slideDown(400);
<% else %> <% else %>
error_form_siret('<%= invalid_siret %>'); error_form_siret('<%= invalid_siret %>');
<% end %> <% end %>

View file

@ -1,18 +0,0 @@
.commentaire
.comment-header
= commentaire.header
.content
= sanitize(commentaire.body)
- if file = commentaire.piece_justificative
.file
= link_to file.content_url, class: 'link', target: '_blank' do
%span.fa.fa-file
%div
= file.original_filename
- elsif commentaire.file.present?
.file
= link_to commentaire.file_url, class: 'link', target: '_blank' do
%span.fa.fa-file
%div
= commentaire.file_identifier

View file

@ -1,10 +0,0 @@
= form_tag(url_for({ controller: 'commentaires', action: :create, dossier_id: dossier_facade.dossier.id, champ_id: dossier_facade.champ_id }), class: 'form-inline', method: 'POST', multipart: true) do
%textarea.form-control.wysihtml5#texte_commentaire{ name: 'texte_commentaire', style: 'width: 100%; margin-bottom: 2%;', rows: '5', placeholder: "Commentaire" }
.row
.col-md-6
%h4.text-primary{ style: 'margin-top: 0px;' } Ajouter un fichier
= file_field_tag "file", accept: Commentaire.new.file.accept_extension_list, style: 'float: left; margin-left: 20px;'
.col-md-6.text-right
= submit_tag 'Envoyer', id: 'save-message', class: 'form-control btn btn-danger', data: { disable: true }

View file

@ -33,8 +33,4 @@
%br %br
= form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f| = form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f|
= f.hidden_field :id = f.hidden_field :id
%label{ style: 'font-weight: normal;' } = f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float: right;', id: 'etape_suivante'
= f.check_box :autorisation_donnees
J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles.
%br
= f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float: right;', id: 'etape_suivante', disabled: :disabled

View file

@ -1,6 +1,6 @@
<% if flash.empty? %> <% if flash.empty? %>
$('.row.etape.etape-2').hide(300, render_new_siret); $('.row.etape.etape-2').hide(300, render_new_siret);
$('.row.etape.etape-2').slideDown(400, the_terms); $('.row.etape.etape-2').slideDown(400);
toggle_etape_1(); toggle_etape_1();
<% else %> <% else %>
error_form_siret('<%= invalid_siret %>'); error_form_siret('<%= invalid_siret %>');

View file

@ -0,0 +1,7 @@
%strong Sujet
%pre
= field.data.subject
%strong Corps
%pre
= field.data.body

View file

@ -1 +0,0 @@
= render partial: 'layouts/left_panels/left_panel_users_recapitulatifcontroller_show'

View file

@ -1,22 +0,0 @@
.link-to-dossiers
= link_to 'retour aux dossiers', dossiers_path
#first-block
.en-cours
%h2 Récapitulatif
.infos
%div= t('dynamics.dossiers.numéro') + @facade.dossier.id.to_s
#menu-block
#infos-block
.split-hr-left
.dossier-state= @facade.dossier.display_state
.split-hr-left
- if current_user.owns?(@facade.dossier) && !@facade.dossier.instruction_commencee?
.text-center.mt-1
= link_to ask_deletion_dossier_path(@facade.dossier), method: :post, class: "btn btn-danger", data: { confirm: "Vous vous apprêtez à supprimer votre dossier ainsi que les informations quil contient. Nous vous rappelons que toute suppression entraine lannulation de la démarche en cours.\n\n Confirmer la suppression ?" } do
Supprimer définitivement
%br
ce dossier

View file

@ -1,24 +0,0 @@
.col-xs-7.main-info
%span{ 'data-toggle' => :tooltip, "data-placement" => :bottom, title: @facade.dossier.procedure.libelle }
= @facade.dossier.procedure.libelle.truncate(60)
.col-lg-3.col-md-3.col-sm-3.col-xs-3.options
.row.centered-option
.col-lg-12.col-md-12.col-sm-12.col-xs-12
#invitations.dropdown-toggle{ 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false }
%i.fa.fa-user
= t('utils.involved')
.badge.progress-bar-info
= @facade.dossier.invites.count
.dropdown-menu.dropdown-menu-right.dropdown-pannel
%h4= t('dynamics.dossiers.invites.title')
%ul
- if @facade.invites.present?
- @facade.invites.each do |invite|
%li= invite.email
- else
= t('dynamics.dossiers.invites.empty')
%li
= form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline', id: 'send-invitation' do
= text_field_tag :invite_email, '', class: 'form-control', placeholder: 'Envoyer une invitation', id: 'invite_email'
= submit_tag 'Ajouter', class: 'btn btn-success', data: { confirm: "Envoyer l'invitation ?" }

View file

@ -12,7 +12,7 @@
locals: { champ: champ, form: champ_form, seen_at: @annotations_privees_seen_at } locals: { champ: champ, form: champ_form, seen_at: @annotations_privees_seen_at }
.send-wrapper .send-wrapper
= f.submit 'Sauvegarder', class: 'button send', data: { disable: true } = f.submit 'Sauvegarder', class: 'button primary send', data: { disable: true }
- else - else
%h2.empty-text Aucune annotation privée %h2.empty-text Aucune annotation privée

View file

@ -44,11 +44,4 @@
= f.label :birthdate, class: "required" = f.label :birthdate, class: "required"
= f.date_field :birthdate, value: @dossier.individual.birthdate, placeholder: 'format : AAAA-MM-JJ', required: true, class: "small" = f.date_field :birthdate, value: @dossier.individual.birthdate, placeholder: 'format : AAAA-MM-JJ', required: true, class: "small"
= fields_for :dossier, @dossier do |df|
= label_tag do
= df.check_box :autorisation_donnees, required: true
J'accepte
= link_to "les CGU", CGU_URL, target: :blank
%span.mandatory *
= f.submit "Continuer", class: "button large primary expand" = f.submit "Continuer", class: "button large primary expand"

View file

@ -1,27 +0,0 @@
%table.table
- dossier.types_de_piece_justificative.order('order_place ASC').each do |tpj|
%tr
%th.piece-libelle
= tpj.mandatory ? tpj.libelle + ' *' : tpj.libelle
%br
.piece-description= tpj.description
%td
- if tpj.lien_demarche.present?
%em
Récupérer le formulaire vierge pour mon dossier :
= link_to "Télécharger", tpj.lien_demarche, target: :blank
%td
- if tpj.api_entreprise
%span.text-success{ id: "piece_justificative_#{tpj.id}" } Nous l'avons récupéré pour vous.
- else
- if !dossier.was_piece_justificative_uploaded_for_type_id?(tpj.id)
= file_field_tag "piece_justificative_#{tpj.id}", accept: PieceJustificative.accept_format, :max_file_size => 6.megabytes
- else
- pj = dossier.retrieve_last_piece_justificative_by_type(tpj.id)
%a{ href: pj.content_url, target: '_blank' }
= pj.original_filename
%span.btn.btn-sm.btn-file.btn-success
Modifier
= file_field_tag "piece_justificative_#{tpj.id}", accept: PieceJustificative.accept_format, :max_file_size => 6.megabytes

View file

@ -1,17 +0,0 @@
#upload-pj-modal.modal.fade{ "aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1" }
.modal-dialog{ :role => "document" }
.modal-content
- @dossier = @facade.dossier
= form_tag(url_for({ controller: '/users/description', action: :pieces_justificatives, dossier_id: @dossier.id }), class: 'form-inline', method: 'PATCH', multipart: true) do
.modal-header
%button.close{ "aria-label" => "Close", "data-dismiss" => "modal", :type => "button" }
%span{ "aria-hidden" => "true" } ×
%h4.modal-title
Modification des documents
.modal-body
= render partial: 'users/description/pieces_justificatives', locals: { dossier: @dossier }
.modal-footer
= submit_tag 'Modification terminée', class: %w(btn btn btn-info), id: 'modification_terminee', data: { disable: true, submit: true }

View file

@ -1,2 +0,0 @@
.col-lg-12.col-md-12.col-sm-12.col-xs-12#users-recapitulatif-dossier-show
= render partial: "dossiers/dossier_show"

View file

@ -31,6 +31,9 @@ Rails.application.routes.draw do
resources :dossiers, only: [:show] resources :dossiers, only: [:show]
resources :demandes, only: [:index] resources :demandes, only: [:index]
resources :services, only: [:index, :show]
post 'demandes/create_administrateur' post 'demandes/create_administrateur'
post 'demandes/refuse_administrateur' post 'demandes/refuse_administrateur'
@ -134,20 +137,11 @@ Rails.application.routes.draw do
namespace :users do namespace :users do
namespace :dossiers do namespace :dossiers do
resources :invites, only: [:index, :show] resources :invites, only: [:index, :show]
post '/commentaire' => 'commentaires#create'
end end
resources :dossiers do resources :dossiers do
get '/add_siret' => 'dossiers/add_siret#show' get '/add_siret' => 'dossiers/add_siret#show'
patch 'pieces_justificatives' => 'description#pieces_justificatives'
# TODO: once these pages will be migrated to the new user design, replace these routes by a redirection
get '/recapitulatif' => 'recapitulatif#show'
post '/recapitulatif/initiate' => 'recapitulatif#initiate'
post '/commentaire' => 'commentaires#create'
get '/carte/position' => 'carte#get_position' get '/carte/position' => 'carte#get_position'
post '/carte/qp' => 'carte#get_qp' post '/carte/qp' => 'carte#get_qp'
post '/carte/cadastre' => 'carte#get_cadastre' post '/carte/cadastre' => 'carte#get_cadastre'
@ -165,6 +159,7 @@ Rails.application.routes.draw do
# Redirection of legacy "/users/dossiers" route to "/dossiers" # Redirection of legacy "/users/dossiers" route to "/dossiers"
get 'dossiers', to: redirect('/dossiers') get 'dossiers', to: redirect('/dossiers')
get 'dossiers/:id/recapitulatif', to: redirect('/dossiers/%{id}')
end end
namespace :gestionnaire do namespace :gestionnaire do

View file

@ -0,0 +1,5 @@
class DropSearchView < ActiveRecord::Migration[5.2]
def change
drop_view :searches, revert_to_version: 4
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2018_09_26_145604) do ActiveRecord::Schema.define(version: 2018_10_02_162757) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -619,18 +619,4 @@ ActiveRecord::Schema.define(version: 2018_09_26_145604) do
add_foreign_key "refused_mails", "procedures" add_foreign_key "refused_mails", "procedures"
add_foreign_key "services", "administrateurs" add_foreign_key "services", "administrateurs"
add_foreign_key "without_continuation_mails", "procedures" add_foreign_key "without_continuation_mails", "procedures"
create_view "searches", sql_definition: <<-SQL
SELECT dossiers.id AS dossier_id,
(((((((((((((((((((((((((((((((((((((((((((((((((((((COALESCE(users.email, ''::character varying))::text || ' '::text) || (COALESCE(france_connect_informations.given_name, ''::character varying))::text) || ' '::text) || (COALESCE(france_connect_informations.family_name, ''::character varying))::text) || ' '::text) || (COALESCE(champs.value, ''::character varying))::text) || ' '::text) || (COALESCE(drop_down_lists.value, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_siren, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_numero_tva_intracommunautaire, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_forme_juridique, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_forme_juridique_code, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_nom_commercial, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_raison_sociale, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_siret_siege_social, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_nom, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.entreprise_prenom, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.association_rna, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.association_titre, ''::character varying))::text) || ' '::text) || COALESCE(etablissements.association_objet, ''::text)) || ' '::text) || (COALESCE(etablissements.siret, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.naf, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.libelle_naf, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.adresse, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.code_postal, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.localite, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.code_insee_localite, ''::character varying))::text) || ' '::text) || (COALESCE(individuals.nom, ''::character varying))::text) || ' '::text) || (COALESCE(individuals.prenom, ''::character varying))::text) || ' '::text) || (COALESCE(pieces_justificatives.content, ''::character varying))::text) AS term
FROM (((((((dossiers
JOIN users ON ((users.id = dossiers.user_id)))
LEFT JOIN france_connect_informations ON ((france_connect_informations.user_id = dossiers.user_id)))
LEFT JOIN champs ON ((champs.dossier_id = dossiers.id)))
LEFT JOIN drop_down_lists ON ((drop_down_lists.type_de_champ_id = champs.type_de_champ_id)))
LEFT JOIN etablissements ON ((etablissements.dossier_id = dossiers.id)))
LEFT JOIN individuals ON ((individuals.dossier_id = dossiers.id)))
LEFT JOIN pieces_justificatives ON ((pieces_justificatives.dossier_id = dossiers.id)));
SQL
end end

View file

@ -162,7 +162,7 @@ describe NewUser::DossiersController, type: :controller do
let(:procedure) { create(:procedure, :for_individual) } let(:procedure) { create(:procedure, :for_individual) }
let(:dossier) { create(:dossier, user: user, procedure: procedure) } let(:dossier) { create(:dossier, user: user, procedure: procedure) }
subject { post :update_identite, params: { id: dossier.id, individual: individual_params, dossier: dossier_params } } subject { post :update_identite, params: { id: dossier.id, individual: individual_params } }
before do before do
sign_in(user) sign_in(user)
@ -171,7 +171,6 @@ describe NewUser::DossiersController, type: :controller do
context 'with correct individual and dossier params' do context 'with correct individual and dossier params' do
let(:individual_params) { { gender: 'M', nom: 'Mouse', prenom: 'Mickey' } } let(:individual_params) { { gender: 'M', nom: 'Mouse', prenom: 'Mickey' } }
let(:dossier_params) { { autorisation_donnees: true } }
it do it do
expect(response).to redirect_to(brouillon_dossier_path(dossier)) expect(response).to redirect_to(brouillon_dossier_path(dossier))
@ -189,7 +188,6 @@ describe NewUser::DossiersController, type: :controller do
context 'when the identite cannot be updated by the user' do context 'when the identite cannot be updated by the user' do
let(:dossier) { create(:dossier, :for_individual, :en_instruction, user: user, procedure: procedure) } let(:dossier) { create(:dossier, :for_individual, :en_instruction, user: user, procedure: procedure) }
let(:individual_params) { { gender: 'M', nom: 'Mouse', prenom: 'Mickey' } } let(:individual_params) { { gender: 'M', nom: 'Mouse', prenom: 'Mickey' } }
let(:dossier_params) { { autorisation_donnees: true } }
it 'redirects to the dossiers list' do it 'redirects to the dossiers list' do
expect(response).to redirect_to(dossiers_path) expect(response).to redirect_to(dossiers_path)
@ -199,11 +197,10 @@ describe NewUser::DossiersController, type: :controller do
context 'with incorrect individual and dossier params' do context 'with incorrect individual and dossier params' do
let(:individual_params) { { gender: '', nom: '', prenom: '' } } let(:individual_params) { { gender: '', nom: '', prenom: '' } }
let(:dossier_params) { { autorisation_donnees: nil } }
it do it do
expect(response).not_to have_http_status(:redirect) expect(response).not_to have_http_status(:redirect)
expect(flash[:alert]).to include("Civilité doit être rempli", "Nom doit être rempli", "Prénom doit être rempli", "Acceptation des CGU doit être coché") expect(flash[:alert]).to include("Civilité doit être rempli", "Nom doit être rempli", "Prénom doit être rempli")
end end
end end
end end

View file

@ -1,81 +0,0 @@
require 'spec_helper'
describe Users::CommentairesController, type: :controller do
let(:dossier) { create(:dossier) }
let(:dossier_id) { dossier.id }
let(:email_commentaire) { 'test@test.com' }
let(:texte_commentaire) { 'Commentaire de test' }
before do
allow(ClamavService).to receive(:safe_file?).and_return(true)
end
describe '#POST create' do
context "when user has no access to dossier" do
before do
sign_in create(:user)
end
subject { post :create, params: { dossier_id: dossier_id, texte_commentaire: texte_commentaire } }
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
it { expect { subject rescue nil }.to change(Commentaire, :count).by(0) }
end
context "when user is invited on dossier" do
let(:user) { create(:user) }
subject { post :create, params: { dossier_id: dossier_id, texte_commentaire: texte_commentaire } }
before do
sign_in user
InviteUser.create(dossier: dossier, user: user, email: user.email, email_sender: "test@test.com")
end
it { expect{ subject }.to change(Commentaire, :count).by(1) }
end
context 'création correct d\'un commentaire' do
subject do
sign_in dossier.user
post :create, params: { dossier_id: dossier_id, texte_commentaire: texte_commentaire }
end
it 'depuis la page récapitulatif' do
subject
expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif")
end
it 'Notification email is not send' do
expect(NotificationMailer).not_to receive(:new_answer)
subject
end
end
context 'when document is upload whith a commentaire', vcr: { cassette_name: 'controllers_sers_commentaires_controller_upload_doc' } do
let(:document_upload) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') }
subject do
sign_in dossier.user
post :create, params: { dossier_id: dossier_id, texte_commentaire: texte_commentaire, file: document_upload }
end
it 'clamav check the pj' do
expect(ClamavService).to receive(:safe_file?)
subject
end
describe 'commentaire created' do
let(:commentaire) { Commentaire.last }
before do
subject
end
it 'have a piece justificative reference' do
expect(commentaire.file.present?).to be true
expect(commentaire.file.class).to eq CommentaireFileUploader
end
end
end
end
end

View file

@ -1,44 +0,0 @@
require 'spec_helper'
describe Users::Dossiers::CommentairesController, type: :controller do
let(:dossier) { create(:dossier) }
let(:texte_commentaire) { 'Commentaire de test' }
describe '#POST create' do
subject {
post :create, params: { dossier_id: dossier.id, texte_commentaire: texte_commentaire }
dossier.reload
}
context 'when invite is connected' do
let!(:invite) { create(:invite, :with_user, dossier: dossier) }
before do
sign_in invite.user
end
it do
subject
is_expected.to redirect_to users_dossiers_invite_path(invite.id)
end
it 'should notify user' do
expect(NotificationMailer).to receive(:new_answer).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
subject
end
end
context 'when user is connected' do
before do
sign_in dossier.user
end
it 'do not send a mail to notify user' do
expect(NotificationMailer).to_not receive(:new_answer)
subject
end
end
end
end

View file

@ -338,7 +338,7 @@ describe Users::DossiersController, type: :controller do
end end
describe 'PUT #update' do describe 'PUT #update' do
let(:params) { { id: dossier_id, dossier: { id: dossier_id, autorisation_donnees: autorisation_donnees, individual_attributes: individual_params } } } let(:params) { { id: dossier_id, dossier: { id: dossier_id, individual_attributes: individual_params } } }
let(:individual_params) { { gender: 'M.', nom: 'Julien', prenom: 'Xavier', birthdate: birthdate } } let(:individual_params) { { gender: 'M.', nom: 'Julien', prenom: 'Xavier', birthdate: birthdate } }
let(:birthdate) { '20/01/1991' } let(:birthdate) { '20/01/1991' }
subject { put :update, params: params } subject { put :update, params: params }
@ -351,8 +351,6 @@ describe Users::DossiersController, type: :controller do
end end
context 'when Checkbox is checked' do context 'when Checkbox is checked' do
let(:autorisation_donnees) { '1' }
context 'procedure not use api carto' do context 'procedure not use api carto' do
it 'redirects to demande' do it 'redirects to demande' do
expect(response).to redirect_to(brouillon_dossier_path(dossier)) expect(response).to redirect_to(brouillon_dossier_path(dossier))
@ -375,20 +373,6 @@ describe Users::DossiersController, type: :controller do
expect(dossier.autorisation_donnees).to be_truthy expect(dossier.autorisation_donnees).to be_truthy
end end
end end
context 'when Checkbox is not checked' do
let(:autorisation_donnees) { '0' }
it 'uses flash alert to display message' do
expect(flash[:alert]).to have_content('La validation des conditions d\'utilisation est obligatoire')
end
it "doesn't update dossier autorisation_donnees" do
dossier.reload
expect(dossier.autorisation_donnees).to be_falsy
end
it { is_expected.to redirect_to users_dossier_path(id: dossier.id) }
end
end end
describe 'DELETE #destroy' do describe 'DELETE #destroy' do

View file

@ -1,54 +0,0 @@
require 'spec_helper'
describe Users::RecapitulatifController, type: :controller do
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:en_construction)) }
let(:bad_dossier_id) { Dossier.count + 100000 }
before do
sign_in dossier.user
end
describe 'GET #show' do
it 'returns http success' do
get :show, params: { dossier_id: dossier.id }
expect(response).to redirect_to(dossier_path(dossier))
end
it 'redirection vers siret si mauvais dossier ID' do
get :show, params: { dossier_id: bad_dossier_id }
expect(response).to redirect_to('/')
end
it_behaves_like "not owner of dossier", :show
describe 'before_action authorized_routes?' do
context 'when dossier have brouillon state' do
before do
dossier.state = Dossier.states.fetch(:brouillon)
dossier.save
get :show, params: { dossier_id: dossier.id }
end
it { is_expected.to redirect_to root_path }
end
end
end
describe 'POST #initiate' do
context 'when an user initiate his dossier' do
before do
post :initiate, params: { dossier_id: dossier.id }
end
it 'dossier change his state for accepte' do
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:en_construction))
end
it 'a message informe user what his dossier is en_construction' do
expect(flash[:notice]).to include('Dossier soumis avec succès.')
end
end
end
end

View file

@ -1,15 +0,0 @@
require 'spec_helper'
describe CommentaireDecorator do
let(:time) { Time.utc(2008, 9, 1, 10, 5, 0) }
let(:commentaire) { Timecop.freeze(time) { create :commentaire } }
let(:decorator) { commentaire.decorate }
describe 'created_at_fr' do
subject { decorator.created_at_fr }
context 'when created_at have a value' do
it { is_expected.to eq time.localtime.strftime('%d/%m/%Y - %H:%M') }
end
end
end

View file

@ -0,0 +1,6 @@
FactoryBot.define do
factory :procedure_presentation do
assign_to { create(:assign_to, procedure: create(:procedure, :with_type_de_champ)) }
sort { { "table" => "user", "column" => "email", "order" => "asc" } }
end
end

View file

@ -150,7 +150,6 @@ feature 'The user' do
def fill_individual def fill_individual
fill_in('individual_prenom', with: 'prenom') fill_in('individual_prenom', with: 'prenom')
fill_in('individual_nom', with: 'nom') fill_in('individual_nom', with: 'nom')
check 'dossier_autorisation_donnees'
click_on 'Continuer' click_on 'Continuer'
expect(page).to have_current_path(brouillon_dossier_path(user_dossier)) expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
end end

View file

@ -38,6 +38,11 @@ describe 'Dossier details:' do
end end
end end
scenario 'the user is redirected from old URLs' do
visit "/users/dossiers/#{dossier.id}/recapitulatif"
expect(page).to have_current_path(dossier_path(dossier))
end
it_behaves_like 'the user can edit the submitted demande' it_behaves_like 'the user can edit the submitted demande'
it_behaves_like 'the user can send messages to the instructeur' it_behaves_like 'the user can send messages to the instructeur'

View file

@ -59,7 +59,6 @@ feature 'linked dropdown lists' do
def fill_individual def fill_individual
fill_in('individual_prenom', with: 'prenom') fill_in('individual_prenom', with: 'prenom')
fill_in('individual_nom', with: 'nom') fill_in('individual_nom', with: 'nom')
check 'dossier_autorisation_donnees'
click_on 'Continuer' click_on 'Continuer'
expect(page).to have_current_path(brouillon_dossier_path(user_dossier)) expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
end end

View file

@ -60,7 +60,6 @@ feature 'user path for dossier creation' do
context 'when validating info entreprise recap page' do context 'when validating info entreprise recap page' do
before do before do
page.check('dossier_autorisation_donnees')
page.find_by_id('etape_suivante').click page.find_by_id('etape_suivante').click
end end
scenario 'user is on edition page' do scenario 'user is on edition page' do

View file

@ -15,7 +15,6 @@ feature 'As a User I wanna create a dossier' do
visit commencer_path(procedure_path: procedure_for_individual.path) visit commencer_path(procedure_path: procedure_for_individual.path)
fill_in 'individual_nom', with: 'Nom' fill_in 'individual_nom', with: 'Nom'
fill_in 'individual_prenom', with: 'Prenom' fill_in 'individual_prenom', with: 'Prenom'
check "dossier_autorisation_donnees"
end end
context "when birthday is asked" do context "when birthday is asked" do
@ -77,14 +76,13 @@ feature 'As a User I wanna create a dossier' do
.to_return(status: 404, body: '') .to_return(status: 404, body: '')
page.find_by_id('dossier-siret').set siret page.find_by_id('dossier-siret').set siret
page.find_by_id('submit-siret').click click_on 'Valider'
wait_for_ajax wait_for_ajax
expect(page).to have_css('#recap-info-entreprise') expect(page).to have_css('#recap-info-entreprise')
check 'dossier_autorisation_donnees' click_on 'Etape suivante'
page.find_by_id('etape_suivante').click
expect(page).to have_current_path(users_dossier_carte_path(procedure_with_siret.dossiers.last.id.to_s)) expect(page).to have_current_path(users_dossier_carte_path(procedure_with_siret.dossiers.last.id.to_s))
page.find_by_id('etape_suivante').click click_on 'Etape suivante'
expect(page).to have_current_path(brouillon_dossier_path(procedure_with_siret.dossiers.last)) expect(page).to have_current_path(brouillon_dossier_path(procedure_with_siret.dossiers.last))
end end
end end

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,8 @@ describe AssignTo, type: :model do
end end
context "with a procedure_presentation" do context "with a procedure_presentation" do
let!(:assign_to) { AssignTo.create } let(:procedure) { create(:procedure) }
let!(:assign_to) { AssignTo.create(procedure: procedure) }
let!(:procedure_presentation) { ProcedurePresentation.create(assign_to: assign_to) } let!(:procedure_presentation) { ProcedurePresentation.create(assign_to: assign_to) }
it { expect(assign_to.procedure_presentation_or_default).to eq(procedure_presentation) } it { expect(assign_to.procedure_presentation_or_default).to eq(procedure_presentation) }

View file

@ -1,20 +1,23 @@
require 'spec_helper' require 'spec_helper'
describe ProcedurePresentation do describe ProcedurePresentation do
let(:assign_to) { create(:assign_to, procedure: create(:procedure, :with_type_de_champ)) }
let(:first_type_de_champ_id) { assign_to.procedure.types_de_champ.first.id.to_s }
let (:procedure_presentation_id) { let (:procedure_presentation_id) {
ProcedurePresentation.create( ProcedurePresentation.create(
assign_to: assign_to,
displayed_fields: [ displayed_fields: [
{ "label" => "test1", "table" => "user" }, { "label" => "test1", "table" => "user", "column" => "email" },
{ "label" => "test2", "table" => "champs" } { "label" => "test2", "table" => "type_de_champ", "column" => first_type_de_champ_id }
], ],
sort: { "table" => "user","column" => "email","order" => "asc" }, sort: { "table" => "user","column" => "email","order" => "asc" },
filters: { "a-suivre" => [], "suivis" => [{ "label" => "label1", "table" => "table1", "column" => "column1" }] } filters: { "a-suivre" => [], "suivis" => [{ "label" => "label1", "table" => "self", "column" => "created_at" }] }
).id ).id
} }
let (:procedure_presentation) { ProcedurePresentation.find(procedure_presentation_id) } let (:procedure_presentation) { ProcedurePresentation.find(procedure_presentation_id) }
describe "#displayed_fields" do describe "#displayed_fields" do
it { expect(procedure_presentation.displayed_fields).to eq([{ "label" => "test1", "table" => "user" }, { "label" => "test2", "table" => "champs" }]) } it { expect(procedure_presentation.displayed_fields).to eq([{ "label" => "test1", "table" => "user", "column" => "email" }, { "label" => "test2", "table" => "type_de_champ", "column" => first_type_de_champ_id }]) }
end end
describe "#sort" do describe "#sort" do
@ -22,6 +25,23 @@ describe ProcedurePresentation do
end end
describe "#filters" do describe "#filters" do
it { expect(procedure_presentation.filters).to eq({ "a-suivre" => [], "suivis" => [{ "label" => "label1", "table" => "table1", "column" => "column1" }] }) } it { expect(procedure_presentation.filters).to eq({ "a-suivre" => [], "suivis" => [{ "label" => "label1", "table" => "self", "column" => "created_at" }] }) }
end
describe 'validation' do
it { expect(build(:procedure_presentation)).to be_valid }
context 'of displayed fields' do
it { expect(build(:procedure_presentation, displayed_fields: [{ "table" => "user", "column" => "reset_password_token", "order" => "asc" }])).to be_invalid }
end
context 'of sort' do
it { expect(build(:procedure_presentation, sort: { "table" => "notifications", "column" => "notifications", "order" => "asc" })).to be_valid }
it { expect(build(:procedure_presentation, sort: { "table" => "user", "column" => "reset_password_token", "order" => "asc" })).to be_invalid }
end
context 'of filters' do
it { expect(build(:procedure_presentation, filters: { "suivis" => [{ "table" => "user", "column" => "reset_password_token", "order" => "asc" }] })).to be_invalid }
end
end end
end end

View file

@ -1,8 +1,38 @@
require 'spec_helper' require 'spec_helper'
describe DossierFieldService do describe DossierFieldService do
let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private) }
describe '#filtered_ids' do describe '#filtered_ids' do
let(:procedure) { create(:procedure) } context 'for type_de_champ table' do
let(:kept_dossier) { create(:dossier, procedure: procedure) }
let(:discarded_dossier) { create(:dossier, procedure: procedure) }
let(:type_de_champ) { procedure.types_de_champ.first }
before do
type_de_champ.champ.create(dossier: kept_dossier, value: 'keep me')
type_de_champ.champ.create(dossier: discarded_dossier, value: 'discard me')
end
subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ', 'column' => type_de_champ.id, 'value' => 'keep' }]) }
it { is_expected.to contain_exactly(kept_dossier.id) }
end
context 'for type_de_champ_private table' do
let(:kept_dossier) { create(:dossier, procedure: procedure) }
let(:discarded_dossier) { create(:dossier, procedure: procedure) }
let(:type_de_champ_private) { procedure.types_de_champ_private.first }
before do
type_de_champ_private.champ.create(dossier: kept_dossier, value: 'keep me')
type_de_champ_private.champ.create(dossier: discarded_dossier, value: 'discard me')
end
subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ_private', 'column' => type_de_champ_private.id, 'value' => 'keep' }]) }
it { is_expected.to contain_exactly(kept_dossier.id) }
end
context 'for etablissement table' do context 'for etablissement table' do
context 'for entreprise_date_creation column' do context 'for entreprise_date_creation column' do
@ -25,5 +55,193 @@ describe DossierFieldService do
it { is_expected.to contain_exactly(kept_dossier.id) } it { is_expected.to contain_exactly(kept_dossier.id) }
end end
end end
context 'for user table' do
let!(:kept_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@keepmail.com')) }
let!(:discarded_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@discard.com')) }
subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'user', 'column' => 'email', 'value' => 'keepmail' }]) }
it { is_expected.to contain_exactly(kept_dossier.id) }
end
end
describe '#sorted_ids' do
let(:gestionnaire) { create(:gestionnaire) }
let(:assign_to) { create(:assign_to, procedure: procedure, gestionnaire: gestionnaire) }
let(:sort) { { 'table' => table, 'column' => column, 'order' => order } }
let(:procedure_presentation) { ProcedurePresentation.create(assign_to: assign_to, sort: sort) }
subject { DossierFieldService.sorted_ids(procedure.dossiers, procedure_presentation, gestionnaire) }
context 'for notifications table' do
let(:table) { 'notifications' }
let(:column) { 'notifications' }
let!(:notified_dossier) { create(:dossier, :en_construction, procedure: procedure) }
let!(:recent_dossier) { create(:dossier, :en_construction, procedure: procedure) }
let!(:older_dossier) { create(:dossier, :en_construction, procedure: procedure) }
before do
notified_dossier.champs.first.touch(time: DateTime.new(2018, 9, 20))
create(:follow, gestionnaire: gestionnaire, dossier: notified_dossier, demande_seen_at: DateTime.new(2018, 9, 10))
recent_dossier.touch(time: DateTime.new(2018, 9, 25))
older_dossier.touch(time: DateTime.new(2018, 5, 13))
end
context 'in ascending order' do
let(:order) { 'asc' }
it { is_expected.to eq([older_dossier, recent_dossier, notified_dossier].map(&:id)) }
end
context 'in descending order' do
let(:order) { 'desc' }
it { is_expected.to eq([notified_dossier, recent_dossier, older_dossier].map(&:id)) }
end
end
context 'for self table' do
let(:table) { 'self' }
let(:column) { 'updated_at' } # All other columns work the same, no extra test required
let(:order) { 'asc' } # Desc works the same, no extra test required
let(:recent_dossier) { create(:dossier, procedure: procedure) }
let(:older_dossier) { create(:dossier, procedure: procedure) }
before do
recent_dossier.touch(time: DateTime.new(2018, 9, 25))
older_dossier.touch(time: DateTime.new(2018, 5, 13))
end
it { is_expected.to eq([older_dossier, recent_dossier].map(&:id)) }
end
context 'for france_connect_information table' do
let(:table) { 'france_connect_information' }
let(:column) { 'given_name' } # All other columns work the same, no extra test required
let(:order) { 'asc' } # Desc works the same, no extra test required
let(:anna_dossier) { create(:dossier, procedure: procedure) }
let(:zacharie_dossier) { create(:dossier, procedure: procedure) }
before do
create(:france_connect_information, given_name: 'Anna', user: anna_dossier.user)
create(:france_connect_information, given_name: 'Zacharie', user: zacharie_dossier.user)
end
it { is_expected.to eq([anna_dossier, zacharie_dossier].map(&:id)) }
end
context 'for type_de_champ table' do
let(:table) { 'type_de_champ' }
let(:column) { procedure.types_de_champ.first.id.to_s }
let(:order) { 'desc' } # Asc works the same, no extra test required
let(:beurre_dossier) { create(:dossier, procedure: procedure) }
let(:tartine_dossier) { create(:dossier, procedure: procedure) }
before do
beurre_dossier.champs.first.update(value: 'beurre')
tartine_dossier.champs.first.update(value: 'tartine')
end
it { is_expected.to eq([tartine_dossier, beurre_dossier].map(&:id)) }
end
context 'for type_de_champ_private table' do
let(:table) { 'type_de_champ_private' }
let(:column) { procedure.types_de_champ_private.first.id.to_s }
let(:order) { 'asc' } # Desc works the same, no extra test required
let(:biere_dossier) { create(:dossier, procedure: procedure) }
let(:vin_dossier) { create(:dossier, procedure: procedure) }
before do
biere_dossier.champs_private.first.update(value: 'biere')
vin_dossier.champs_private.first.update(value: 'vin')
end
it { is_expected.to eq([biere_dossier, vin_dossier].map(&:id)) }
end
context 'for other tables' do
# All other columns and tables work the same so its ok to test only one
let(:table) { 'etablissement' }
let(:column) { 'code_postal' }
let(:order) { 'asc' } # Desc works the same, no extra test required
let!(:huitieme_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75008')) }
let!(:vingtieme_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75020')) }
it { is_expected.to eq([huitieme_dossier, vingtieme_dossier].map(&:id)) }
end
end
describe '#get_value' do
subject { DossierFieldService.get_value(dossier, table, column) }
context 'for self table' do
let(:table) { 'self' }
let(:column) { 'updated_at' } # All other columns work the same, no extra test required
let(:dossier) { create(:dossier, procedure: procedure) }
before { dossier.touch(time: DateTime.new(2018, 9, 25)) }
it { is_expected.to eq(DateTime.new(2018, 9, 25)) }
end
context 'for user table' do
let(:table) { 'user' }
let(:column) { 'email' }
let(:dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'bla@yopmail.com')) }
it { is_expected.to eq('bla@yopmail.com') }
end
context 'for france_connect_information table' do
let(:table) { 'france_connect_information' }
let(:column) { 'given_name' } # All other columns work the same, no extra test required
let(:dossier) { create(:dossier, procedure: procedure) }
before { create(:france_connect_information, given_name: 'Anna', user: dossier.user) }
it { is_expected.to eq('Anna') }
end
context 'for etablissement table' do
let(:table) { 'etablissement' }
let(:column) { 'code_postal' } # All other columns work the same, no extra test required
let!(:dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75008')) }
it { is_expected.to eq('75008') }
end
context 'for type_de_champ table' do
let(:table) { 'type_de_champ' }
let(:column) { procedure.types_de_champ.first.id.to_s }
let(:dossier) { create(:dossier, procedure: procedure) }
before { dossier.champs.first.update(value: 'kale') }
it { is_expected.to eq('kale') }
end
context 'for type_de_champ_private table' do
let(:table) { 'type_de_champ_private' }
let(:column) { procedure.types_de_champ_private.first.id.to_s }
let(:dossier) { create(:dossier, procedure: procedure) }
before { dossier.champs_private.first.update(value: 'quinoa') }
it { is_expected.to eq('quinoa') }
end
end end
end end

View file

@ -68,24 +68,5 @@ describe UserRoutesAuthorizationService do
end end
end end
end end
describe 'recapitulatif' do
let(:controller) { Users::RecapitulatifController }
describe 'brouillon' do
let(:state) { Dossier.states.fetch(:brouillon) }
it { is_expected.to be_falsey }
end
describe 'en_construction' do
let(:state) { Dossier.states.fetch(:en_construction) }
it { is_expected.to be_truthy }
end
describe 'accepte' do
let(:state) { Dossier.states.fetch(:accepte) }
it { is_expected.to be_truthy }
end
end
end end
end end

View file

@ -1,71 +0,0 @@
require 'spec_helper'
describe 'dossiers/_infos_dossier.html.haml', type: :view do
describe "champs rendering" do
let(:dossier) { create(:dossier, :with_entreprise, procedure: create(:procedure, :with_api_carto, :with_type_de_champ)) }
before do
champs.each do |champ|
champ.value = ((0...8).map { (65 + rand(26)).chr }.join)
champ.save
end
assign(:facade, DossierFacades.new(dossier.id, dossier.user.email))
render
end
describe 'every champs are present on the page' do
let(:champs) { dossier.champs }
it { expect(rendered).to have_content(champs.first.libelle) }
it { expect(rendered).to have_content(champs.first.value) }
it { expect(rendered).to have_content(champs.last.libelle) }
it { expect(rendered).to have_content(champs.last.value) }
end
end
describe "oui_non champ rendering" do
let(:dossier_with_yes_no) { create(:dossier, procedure: create(:procedure, :with_yes_no)) }
context "with the true value" do
before do
oui_non_champ = dossier_with_yes_no.champs.first
oui_non_champ.value = 'true'
oui_non_champ.save
assign(:facade, DossierFacades.new(dossier_with_yes_no.id, dossier_with_yes_no.user.email))
render
end
it { expect(rendered).to have_content("Oui") }
end
context "with the false value" do
before do
oui_non_champ = dossier_with_yes_no.champs.first
oui_non_champ.value = 'false'
oui_non_champ.save
assign(:facade, DossierFacades.new(dossier_with_yes_no.id, dossier_with_yes_no.user.email))
render
end
it { expect(rendered).to have_content("Non") }
end
context "with no value" do
before do
oui_non_champ = dossier_with_yes_no.champs.first
oui_non_champ.value = nil
oui_non_champ.save
assign(:facade, DossierFacades.new(dossier_with_yes_no.id, dossier_with_yes_no.user.email))
render
end
it { expect(rendered).not_to have_content("Oui") }
it { expect(rendered).not_to have_content("Non") }
end
end
end

View file

@ -10,23 +10,11 @@ describe 'dossiers/show.html.haml', type: :view do
render render
end end
it 'have autorisation_donnees check box' do
expect(rendered).to have_css('#dossier_autorisation_donnees')
end
context "sur la page d'information d'un SIRET" do context "sur la page d'information d'un SIRET" do
it 'Le formulaire envoie vers /users/dossiers/:dossier_id en #POST' do it 'Le formulaire envoie vers /users/dossiers/:dossier_id en #POST' do
expect(rendered).to have_selector("form[action='/users/dossiers'][method=post]") expect(rendered).to have_selector("form[action='/users/dossiers'][method=post]")
end end
it "la checkbox d'information est présente" do
expect(rendered).to have_css('#dossier_autorisation_donnees')
end
it "le texte d'information des droits est correct" do
expect(rendered).to have_content("J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles.")
end
it "les informations de l'entreprise sont présents" do it "les informations de l'entreprise sont présents" do
expect(rendered).to have_content('Siret') expect(rendered).to have_content('Siret')
end end

View file

@ -1,65 +0,0 @@
require 'spec_helper'
describe 'layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml', type: :view do
let(:dossier) { create(:dossier, :with_entreprise, state: state, procedure: create(:procedure, :with_api_carto, :with_two_type_de_piece_justificative, for_individual: true, individual_with_siret: true)) }
let(:dossier_id) { dossier.id }
let(:state) { Dossier.states.fetch(:brouillon) }
before do
sign_in dossier.user
assign(:facade, DossierFacades.new(dossier.id, dossier.user.email))
end
context 'buttons to change dossier state' do
context 'when dossier state is en_construction' do
let(:state) { Dossier.states.fetch(:en_construction) }
before do
render
end
it { expect(rendered).to have_content('En construction') }
end
context 'when dossier state is accepte' do
let(:state) { Dossier.states.fetch(:accepte) }
before do
render
end
it { expect(rendered).to have_content('Accepté') }
it 'button Editer mon dossier n\'est plus present' do
expect(rendered).not_to have_css('#maj_infos')
expect(rendered).not_to have_content('Modifier mon dossier')
end
end
context 'when dossier state is refuse' do
let(:state) { Dossier.states.fetch(:refuse) }
before do
render
end
it { expect(rendered).to have_content('Refusé') }
it 'button Editer mon dossier n\'est plus present' do
expect(rendered).not_to have_css('#maj_infos')
expect(rendered).not_to have_content('Modifier mon dossier')
end
end
context 'when dossier state is sans_suite' do
let(:state) { Dossier.states.fetch(:sans_suite) }
before do
render
end
it { expect(rendered).to have_content('Sans suite') }
it 'button Editer mon dossier n\'est plus present' do
expect(rendered).not_to have_css('#maj_infos')
expect(rendered).not_to have_content('Modifier mon dossier')
end
end
end
end

View file

@ -1,103 +0,0 @@
require 'spec_helper'
describe 'users/recapitulatif/show.html.haml', type: :view do
let(:dossier) { create(:dossier, :with_entreprise, state: state, procedure: create(:procedure, :with_api_carto, :with_two_type_de_piece_justificative, for_individual: true, individual_with_siret: true)) }
let(:dossier_id) { dossier.id }
let(:state) { Dossier.states.fetch(:brouillon) }
before do
sign_in dossier.user
assign(:facade, DossierFacades.new(dossier.id, dossier.user.email))
end
context 'sur la rendered recapitulative' do
context 'test de composition de la page' do
before do
render
end
it 'la section infos dossier est présente' do
expect(rendered).to have_selector('#infos-dossiers')
end
it 'le flux de commentaire est présent' do
expect(rendered).to have_selector('#messages')
end
describe 'les liens de modifications' do
context 'lien description' do
it 'le lien vers description est présent' do
expect(rendered).to have_css('#maj_infos')
end
it 'le lien vers l édition est correct' do
expect(rendered).to have_selector("a[id=maj_infos][href='/dossiers/#{dossier_id}/brouillon']")
end
end
context 'lien carte' do
it 'le lien vers carte est présent' do
expect(rendered).to have_css('#maj_pj')
end
end
context 'lien carte' do
it 'le lien vers le renseignement un SIRET est présent' do
expect(rendered).to have_css('#add_siret')
end
end
context 'lien carte' do
it 'le lien vers carte est présent' do
expect(rendered).to have_css('#maj_carte')
end
it 'le lien vers description est correct' do
expect(rendered).to have_selector("a[id=maj_carte][href='/users/dossiers/#{dossier_id}/carte']")
end
end
end
end
context 'when dossier state is en_construction' do
let(:state) { Dossier.states.fetch(:en_construction) }
before do
render
end
it 'button Modifier les document est present' do
expect(rendered).to have_content('Modifier les documents')
expect(rendered).to have_css('#upload-pj-modal')
end
end
context 'when invite is logged' do
let!(:invite_user) { create(:user, email: 'invite@octo.com') }
before do
create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier, type: 'InviteUser') }
sign_out dossier.user
sign_in invite_user
render
end
describe 'les liens de modifications' do
it 'describe link is not present' do
expect(rendered).to have_css('#maj_infos')
end
it 'map link is present' do
expect(rendered).to have_css('#maj_carte')
end
it 'PJ link is present' do
expect(rendered).to have_css('#maj_pj')
end
it 'archive link is present' do
expect(rendered).not_to have_content('Archiver')
end
end
end
end
end