commit
b2f2a9677b
50 changed files with 416 additions and 129 deletions
1
app/assets/images/icons/reply.svg
Normal file
1
app/assets/images/icons/reply.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M74.524 65.23l-3.498-5.592c-6.497-10.413-18.79-17.191-33.783-17.673l-.12 17.602c.1 1.265-1.002 1.856-1.744 1.346L3.101 32.538c-2.57-2.624 0-4.317 0-4.317L34.454 2.483c1.544-1.174 2.802-.77 2.801 1.16l-.112 17.33c20.69.868 37.013 18.232 37.281 37.996l.06 4.424zM4.76 30.905l28.786 23.912v-16.42h1.899c14.593 0 26.986 5.524 34.982 14.299-2.698-15.91-17.291-28.059-34.982-28.059h-1.9V8.535z" stroke-width="3.182" stroke-linejoin="round" transform="matrix(.31704 0 0 .3003 -.132 1.934)" fill="#0069cc" stroke="#0069cc"/></svg>
|
After Width: | Height: | Size: 594 B |
|
@ -145,12 +145,27 @@
|
||||||
border: solid 1px $border-grey;
|
border: solid 1px $border-grey;
|
||||||
padding: $default-padding;
|
padding: $default-padding;
|
||||||
|
|
||||||
|
&.small {
|
||||||
|
padding: $default-padding / 2;
|
||||||
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
background-color: $border-grey;
|
background-color: $border-grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.small {
|
&:focus {
|
||||||
padding: $default-padding / 2;
|
border: 1px solid $blue;
|
||||||
|
box-shadow: 0px 0px 2px 1px $blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide the browser default invalidity indicator until the field is touched
|
||||||
|
&:invalid:not(:focus) {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.touched:invalid {
|
||||||
|
border: 1px solid $dark-red;
|
||||||
|
box-shadow: 0px 0px 2px 1px $dark-red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,17 +203,6 @@
|
||||||
max-width: 180px;
|
max-width: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:invalid,
|
|
||||||
textarea:invalid {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input.touched:invalid,
|
|
||||||
textarea.touched:invalid {
|
|
||||||
border: 1px solid $dark-red;
|
|
||||||
box-shadow: 0px 0px 5px $dark-red;
|
|
||||||
}
|
|
||||||
|
|
||||||
select,
|
select,
|
||||||
.select2-selection {
|
.select2-selection {
|
||||||
// hack found here: https://stackoverflow.com/questions/1895476/how-to-style-a-select-dropdown-with-css-only-without-javascript
|
// hack found here: https://stackoverflow.com/questions/1895476/how-to-style-a-select-dropdown-with-css-only-without-javascript
|
||||||
|
|
|
@ -91,6 +91,10 @@
|
||||||
background-image: image-url("icons/mail.svg");
|
background-image: image-url("icons/mail.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.reply {
|
||||||
|
background-image: image-url("icons/reply.svg");
|
||||||
|
}
|
||||||
|
|
||||||
&.search {
|
&.search {
|
||||||
background-image: image-url("icons/search-blue.svg");
|
background-image: image-url("icons/search-blue.svg");
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,4 +38,8 @@
|
||||||
.attachment-link {
|
.attachment-link {
|
||||||
margin-top: $default-spacer;
|
margin-top: $default-spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-answer-button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ class Admin::ProceduresController < AdminController
|
||||||
include SmartListing::Helper::ControllerExtensions
|
include SmartListing::Helper::ControllerExtensions
|
||||||
helper SmartListing::Helper
|
helper SmartListing::Helper
|
||||||
|
|
||||||
before_action :retrieve_procedure, only: [:show, :edit, :delete_logo, :delete_deliberation, :delete_notice]
|
before_action :retrieve_procedure, only: [:show, :edit, :delete_logo, :delete_deliberation, :delete_notice, :monavis, :update_monavis]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if current_administrateur.procedures.count != 0
|
if current_administrateur.procedures.count != 0
|
||||||
|
@ -198,6 +198,18 @@ class Admin::ProceduresController < AdminController
|
||||||
render layout: 'application'
|
render layout: 'application'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def monavis
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_monavis
|
||||||
|
if !@procedure.update(procedure_params)
|
||||||
|
flash.now.alert = @procedure.errors.full_messages
|
||||||
|
else
|
||||||
|
flash.notice = 'le champ MonAvis a bien été mis à jour'
|
||||||
|
end
|
||||||
|
render 'monavis'
|
||||||
|
end
|
||||||
|
|
||||||
def active_class
|
def active_class
|
||||||
@active_class = 'active'
|
@active_class = 'active'
|
||||||
end
|
end
|
||||||
|
@ -265,7 +277,7 @@ class Admin::ProceduresController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure_params
|
def procedure_params
|
||||||
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on]
|
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on, :monavis_embed]
|
||||||
if @procedure&.locked?
|
if @procedure&.locked?
|
||||||
params.require(:procedure).permit(*editable_params)
|
params.require(:procedure).permit(*editable_params)
|
||||||
else
|
else
|
||||||
|
|
5
app/helpers/mailer_helper.rb
Normal file
5
app/helpers/mailer_helper.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module MailerHelper
|
||||||
|
def round_button(text, url)
|
||||||
|
render 'shared/mailer_round_button', text: text, url: url
|
||||||
|
end
|
||||||
|
end
|
9
app/helpers/messagerie_helper.rb
Normal file
9
app/helpers/messagerie_helper.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
module MessagerieHelper
|
||||||
|
def show_reply_button(commentaire, connected_user)
|
||||||
|
commentaire.dossier.present? &&
|
||||||
|
commentaire.dossier.messagerie_available? &&
|
||||||
|
commentaire.dossier.user == connected_user &&
|
||||||
|
!commentaire.sent_by?(connected_user) &&
|
||||||
|
commentaire.dossier.commentaires.last == commentaire
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,4 +2,22 @@ class ApplicationMailer < ActionMailer::Base
|
||||||
helper :application # gives access to all helpers defined within `application_helper`.
|
helper :application # gives access to all helpers defined within `application_helper`.
|
||||||
default from: "demarches-simplifiees.fr <#{CONTACT_EMAIL}>"
|
default from: "demarches-simplifiees.fr <#{CONTACT_EMAIL}>"
|
||||||
layout 'mailer'
|
layout 'mailer'
|
||||||
|
|
||||||
|
# Attach the procedure logo to the email (if any).
|
||||||
|
# Returns the attachment url.
|
||||||
|
def attach_logo(procedure)
|
||||||
|
return nil if !procedure.logo?
|
||||||
|
|
||||||
|
begin
|
||||||
|
logo_filename = procedure.logo.filename
|
||||||
|
attachments.inline[logo_filename] = procedure.logo.read
|
||||||
|
attachments[logo_filename].url
|
||||||
|
|
||||||
|
rescue StandardError => e
|
||||||
|
# A problem occured when reading logo, maybe the logo is missing and we should clean the procedure to remove logo reference ?
|
||||||
|
Raven.extra_context(procedure_id: procedure.id)
|
||||||
|
Raven.capture_exception(e)
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +1,28 @@
|
||||||
# Preview all emails at http://localhost:3000/rails/mailers/dossier_mailer
|
# Preview all emails at http://localhost:3000/rails/mailers/dossier_mailer
|
||||||
class DossierMailer < ApplicationMailer
|
class DossierMailer < ApplicationMailer
|
||||||
|
helper ServiceHelper
|
||||||
|
helper MailerHelper
|
||||||
|
|
||||||
layout 'mailers/layout'
|
layout 'mailers/layout'
|
||||||
|
|
||||||
def notify_new_draft(dossier)
|
def notify_new_draft(dossier)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
subject = "Retrouvez votre brouillon pour la démarche \"#{dossier.procedure.libelle}\""
|
@service = dossier.procedure.service
|
||||||
|
@logo_url = attach_logo(dossier.procedure)
|
||||||
|
|
||||||
mail(to: dossier.user.email, subject: subject)
|
subject = "Retrouvez votre brouillon pour la démarche « #{dossier.procedure.libelle} »"
|
||||||
|
|
||||||
|
mail(to: dossier.user.email, subject: subject) do |format|
|
||||||
|
format.html { render layout: 'mailers/notification' }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_new_answer(dossier)
|
def notify_new_answer(dossier)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
subject = "Nouveau message pour votre dossier nº #{dossier.id}"
|
@service = dossier.procedure.service
|
||||||
|
@logo_url = attach_logo(dossier.procedure)
|
||||||
|
|
||||||
|
subject = "Nouveau message pour votre dossier nº #{dossier.id} (#{dossier.procedure.libelle})"
|
||||||
|
|
||||||
mail(to: dossier.user.email, subject: subject) do |format|
|
mail(to: dossier.user.email, subject: subject) do |format|
|
||||||
format.html { render layout: 'mailers/notification' }
|
format.html { render layout: 'mailers/notification' }
|
||||||
|
@ -20,21 +31,21 @@ class DossierMailer < ApplicationMailer
|
||||||
|
|
||||||
def notify_deletion_to_user(deleted_dossier, to_email)
|
def notify_deletion_to_user(deleted_dossier, to_email)
|
||||||
@deleted_dossier = deleted_dossier
|
@deleted_dossier = deleted_dossier
|
||||||
subject = "Votre dossier n° #{@deleted_dossier.dossier_id} a bien été supprimé"
|
subject = "Votre dossier nº #{@deleted_dossier.dossier_id} a bien été supprimé"
|
||||||
|
|
||||||
mail(to: to_email, subject: subject)
|
mail(to: to_email, subject: subject)
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_deletion_to_administration(deleted_dossier, to_email)
|
def notify_deletion_to_administration(deleted_dossier, to_email)
|
||||||
@deleted_dossier = deleted_dossier
|
@deleted_dossier = deleted_dossier
|
||||||
subject = "Le dossier n° #{@deleted_dossier.dossier_id} a été supprimé à la demande de l'usager"
|
subject = "Le dossier nº #{@deleted_dossier.dossier_id} a été supprimé à la demande de l'usager"
|
||||||
|
|
||||||
mail(to: to_email, subject: subject)
|
mail(to: to_email, subject: subject)
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_unhide_to_user(dossier)
|
def notify_unhide_to_user(dossier)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
subject = "Votre dossier n° #{@dossier.id} n'a pas pu être supprimé"
|
subject = "Votre dossier nº #{@dossier.id} n'a pas pu être supprimé"
|
||||||
|
|
||||||
mail(to: dossier.user.email, subject: subject)
|
mail(to: dossier.user.email, subject: subject)
|
||||||
end
|
end
|
||||||
|
@ -42,23 +53,14 @@ class DossierMailer < ApplicationMailer
|
||||||
def notify_undelete_to_user(dossier)
|
def notify_undelete_to_user(dossier)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@dossier_kind = dossier.brouillon? ? 'brouillon' : 'dossier'
|
@dossier_kind = dossier.brouillon? ? 'brouillon' : 'dossier'
|
||||||
@subject = "Votre #{@dossier_kind} n° #{@dossier.id} est à nouveau accessible"
|
@subject = "Votre #{@dossier_kind} nº #{@dossier.id} est à nouveau accessible"
|
||||||
|
|
||||||
mail(to: dossier.user.email, subject: @subject)
|
|
||||||
end
|
|
||||||
|
|
||||||
def notify_unmigrated_to_user(dossier, new_procedure)
|
|
||||||
@dossier = dossier
|
|
||||||
@dossier_kind = dossier.brouillon? ? 'brouillon' : 'dossier'
|
|
||||||
@subject = "Changement de procédure pour votre #{@dossier_kind} n° #{@dossier.id}"
|
|
||||||
@new_procedure = new_procedure
|
|
||||||
|
|
||||||
mail(to: dossier.user.email, subject: @subject)
|
mail(to: dossier.user.email, subject: @subject)
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_revert_to_instruction(dossier)
|
def notify_revert_to_instruction(dossier)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@subject = "Votre dossier n° #{@dossier.id} est en train d'être réexaminé"
|
@subject = "Votre dossier nº #{@dossier.id} est en train d'être réexaminé"
|
||||||
|
|
||||||
mail(to: dossier.user.email, subject: @subject)
|
mail(to: dossier.user.email, subject: @subject)
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,20 +38,9 @@ class NotificationMailer < ApplicationMailer
|
||||||
|
|
||||||
create_commentaire_for_notification(dossier, subject, body)
|
create_commentaire_for_notification(dossier, subject, body)
|
||||||
|
|
||||||
if dossier.procedure.logo?
|
|
||||||
begin
|
|
||||||
logo_filename = dossier.procedure.logo.filename
|
|
||||||
attachments.inline[logo_filename] = dossier.procedure.logo.read
|
|
||||||
@logo_url = attachments[logo_filename].url
|
|
||||||
rescue StandardError => e
|
|
||||||
# A problem occured when reading logo, maybe the logo is missing and we should clean the procedure to remove logo reference ?
|
|
||||||
Raven.extra_context(procedure_id: dossier.procedure.id)
|
|
||||||
Raven.capture_exception(e)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@service = dossier.procedure.service
|
@service = dossier.procedure.service
|
||||||
|
@logo_url = attach_logo(dossier.procedure)
|
||||||
|
|
||||||
mail(subject: subject, to: email) do |format|
|
mail(subject: subject, to: email) do |format|
|
||||||
# rubocop:disable Rails/OutputSafety
|
# rubocop:disable Rails/OutputSafety
|
||||||
|
|
|
@ -59,14 +59,20 @@ module TagsSubstitutionConcern
|
||||||
{
|
{
|
||||||
libelle: 'lien attestation',
|
libelle: 'lien attestation',
|
||||||
description: '',
|
description: '',
|
||||||
lambda: -> (d) {
|
lambda: -> (d) { external_link(attestation_dossier_url(d)) },
|
||||||
links = [external_link(attestation_dossier_url(d))]
|
|
||||||
if d.justificatif_motivation.attached?
|
|
||||||
links.push external_link("Télécharger le justificatif", url_for_justificatif_motivation(d))
|
|
||||||
end
|
|
||||||
links.join "<br />\n"
|
|
||||||
},
|
|
||||||
available_for_states: [Dossier.states.fetch(:accepte)]
|
available_for_states: [Dossier.states.fetch(:accepte)]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
libelle: 'lien document justificatif',
|
||||||
|
description: '',
|
||||||
|
lambda: -> (d) {
|
||||||
|
if d.justificatif_motivation.attached?
|
||||||
|
external_link(url_for_justificatif_motivation(d), "Télécharger le document justificatif")
|
||||||
|
else
|
||||||
|
return "[l'instructeur n'a pas joint de document supplémentaire]"
|
||||||
|
end
|
||||||
|
},
|
||||||
|
available_for_states: Dossier::TERMINE
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Mails
|
||||||
|
|
||||||
SLUG = "closed_mail"
|
SLUG = "closed_mail"
|
||||||
DISPLAYED_NAME = "Accusé d'acceptation"
|
DISPLAYED_NAME = "Accusé d'acceptation"
|
||||||
DEFAULT_SUBJECT = 'Votre dossier demarches-simplifiees.fr nº --numéro du dossier-- a été accepté'
|
DEFAULT_SUBJECT = 'Votre dossier nº --numéro du dossier-- a été accepté (--libellé démarche--)'
|
||||||
DOSSIER_STATE = Dossier.states.fetch(:accepte)
|
DOSSIER_STATE = Dossier.states.fetch(:accepte)
|
||||||
|
|
||||||
def self.default_template_name_for_procedure(procedure)
|
def self.default_template_name_for_procedure(procedure)
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Mails
|
||||||
SLUG = "initiated_mail"
|
SLUG = "initiated_mail"
|
||||||
DEFAULT_TEMPLATE_NAME = "notification_mailer/initiated_mail"
|
DEFAULT_TEMPLATE_NAME = "notification_mailer/initiated_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de réception'
|
DISPLAYED_NAME = 'Accusé de réception'
|
||||||
DEFAULT_SUBJECT = 'Votre dossier demarches-simplifiees.fr nº --numéro du dossier-- a bien été reçu'
|
DEFAULT_SUBJECT = 'Votre dossier nº --numéro du dossier-- a bien été reçu (--libellé démarche--)'
|
||||||
DOSSIER_STATE = Dossier.states.fetch(:en_construction)
|
DOSSIER_STATE = Dossier.states.fetch(:en_construction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Mails
|
||||||
SLUG = "received_mail"
|
SLUG = "received_mail"
|
||||||
DEFAULT_TEMPLATE_NAME = "notification_mailer/received_mail"
|
DEFAULT_TEMPLATE_NAME = "notification_mailer/received_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de passage en instruction'
|
DISPLAYED_NAME = 'Accusé de passage en instruction'
|
||||||
DEFAULT_SUBJECT = 'Votre dossier demarches-simplifiees.fr nº --numéro du dossier-- va être instruit'
|
DEFAULT_SUBJECT = 'Votre dossier nº --numéro du dossier-- va être instruit (--libellé démarche--)'
|
||||||
DOSSIER_STATE = Dossier.states.fetch(:en_instruction)
|
DOSSIER_STATE = Dossier.states.fetch(:en_instruction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Mails
|
||||||
SLUG = "refused_mail"
|
SLUG = "refused_mail"
|
||||||
DEFAULT_TEMPLATE_NAME = "notification_mailer/refused_mail"
|
DEFAULT_TEMPLATE_NAME = "notification_mailer/refused_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de rejet du dossier'
|
DISPLAYED_NAME = 'Accusé de rejet du dossier'
|
||||||
DEFAULT_SUBJECT = 'Votre dossier demarches-simplifiees.fr nº --numéro du dossier-- a été refusé'
|
DEFAULT_SUBJECT = 'Votre dossier nº --numéro du dossier-- a été refusé (--libellé démarche--)'
|
||||||
DOSSIER_STATE = Dossier.states.fetch(:refuse)
|
DOSSIER_STATE = Dossier.states.fetch(:refuse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Mails
|
||||||
SLUG = "without_continuation"
|
SLUG = "without_continuation"
|
||||||
DEFAULT_TEMPLATE_NAME = "notification_mailer/without_continuation_mail"
|
DEFAULT_TEMPLATE_NAME = "notification_mailer/without_continuation_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de classement sans suite'
|
DISPLAYED_NAME = 'Accusé de classement sans suite'
|
||||||
DEFAULT_SUBJECT = 'Votre dossier demarches-simplifiees.fr nº --numéro du dossier-- a été classé sans suite'
|
DEFAULT_SUBJECT = 'Votre dossier nº --numéro du dossier-- a été classé sans suite (--libellé démarche--)'
|
||||||
DOSSIER_STATE = Dossier.states.fetch(:sans_suite)
|
DOSSIER_STATE = Dossier.states.fetch(:sans_suite)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Procedure < ApplicationRecord
|
||||||
validates :duree_conservation_dossiers_hors_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, if: :durees_conservation_required
|
validates :duree_conservation_dossiers_hors_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, if: :durees_conservation_required
|
||||||
validates :duree_conservation_dossiers_dans_ds, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_DUREE_CONSERVATION }, unless: :durees_conservation_required
|
validates :duree_conservation_dossiers_dans_ds, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_DUREE_CONSERVATION }, unless: :durees_conservation_required
|
||||||
validates :duree_conservation_dossiers_hors_ds, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, unless: :durees_conservation_required
|
validates :duree_conservation_dossiers_hors_ds, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, unless: :durees_conservation_required
|
||||||
|
validates_with MonAvisEmbedValidator
|
||||||
before_save :update_juridique_required
|
before_save :update_juridique_required
|
||||||
before_save :update_durees_conservation_required
|
before_save :update_durees_conservation_required
|
||||||
before_create :ensure_path_exists
|
before_create :ensure_path_exists
|
||||||
|
|
9
app/validators/mon_avis_embed_validator.rb
Normal file
9
app/validators/mon_avis_embed_validator.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class MonAvisEmbedValidator < ActiveModel::Validator
|
||||||
|
def validate(record)
|
||||||
|
# We need to ensure the embed code is not any random string in order to avoid injections
|
||||||
|
r = Regexp.new('<a href="https://monavis.numerique.gouv.fr/Demarches/\d+.*key=[[:alnum:]]+.*">\s*<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-blanc|bleu.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />\s*</a>', Regexp::MULTILINE)
|
||||||
|
if record.monavis_embed.present? && !r.match?(record.monavis_embed)
|
||||||
|
record.errors[:base] << "Le code fourni ne correspond pas au format des codes MonAvis reconnus par la plateforme."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
app/views/admin/procedures/_monavis.html.haml
Normal file
16
app/views/admin/procedures/_monavis.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
.form-group
|
||||||
|
%h3 Insérer un lien vers « MonAvis »
|
||||||
|
%p
|
||||||
|
Proposez aux usagers de donner un avis sur votre démarche. Pour ce faire, vous devez précédemment aller sur «
|
||||||
|
%a{ :href => "https://monavis.numerique.gouv.fr" } https://monavis.numerique.gouv.fr
|
||||||
|
», créer un compte, et référencer là démarche que vous venez de publier.
|
||||||
|
|
||||||
|
%p
|
||||||
|
Dès que vous avez effectué le référencement de celle-ci, vous pouvez suivre le guide d’intégration du bouton que vous trouverez à
|
||||||
|
%a{ :href => "https://monavis.numerique.gouv.fr/Aide/Int%C3%A9gration%20du%20bouton%20MonAvis" } l’adresse suivante.
|
||||||
|
|
||||||
|
%p Une fois en possession du code généré sur le site MonAvis, vous pouvez le coller dans le champ ci-dessous :
|
||||||
|
|
||||||
|
.form-group
|
||||||
|
= f.label :monavis_embed, "Mon avis"
|
||||||
|
= f.text_area :monavis_embed, rows: '6', placeholder: '<a href="https://monavis.numerique.gouv.fr/Demarches/123456?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d4"><img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-bleu.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" /></a>', class: 'form-control'
|
6
app/views/admin/procedures/monavis.html.haml
Normal file
6
app/views/admin/procedures/monavis.html.haml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.row.white-back
|
||||||
|
#procedure_new.section.section-label
|
||||||
|
= form_for @procedure, url: url_for({ controller: 'admin/procedures', action: :update_monavis, id: @procedure.id }), multipart: true do |f|
|
||||||
|
= render partial: 'monavis', locals: { f: f }
|
||||||
|
.text-right
|
||||||
|
= f.button 'Enregistrer', class: 'btn btn-success'
|
|
@ -2,10 +2,12 @@
|
||||||
Bonjour,
|
Bonjour,
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Un nouveau message est disponible dans votre espace demarches-simplifiees.fr.
|
L’administration en charge de votre dossier vous a
|
||||||
|
%strong envoyé un nouveau message.
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Pour le consulter, merci de vous rendre sur
|
Pour le consulter et y répondre, cliquez sur le bouton ci-dessous :
|
||||||
= link_to messagerie_dossier_url(@dossier), messagerie_dossier_url(@dossier), target: '_blank', rel:'noopener'
|
|
||||||
|
|
||||||
= render partial: "layouts/mailers/signature"
|
= round_button('Lire le message', messagerie_dossier_url(@dossier))
|
||||||
|
|
||||||
|
= render partial: "layouts/mailers/signature", locals: { service: @service }
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
Bonjour,
|
Bonjour,
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Vous pouvez retrouver et compléter le brouillon que vous avez créé pour la démarche
|
Vous avez commencé à remplir un dossier pour la démarche « #{@dossier.procedure.libelle} ».
|
||||||
%strong= @dossier.procedure.libelle
|
|
||||||
à l'adresse suivante :
|
%p
|
||||||
|
Vous pouvez
|
||||||
|
%strong retrouver et compléter votre dossier
|
||||||
|
à l’adresse suivante :
|
||||||
= link_to dossier_url(@dossier), dossier_url(@dossier), target: '_blank', rel: 'noopener'
|
= link_to dossier_url(@dossier), dossier_url(@dossier), target: '_blank', rel: 'noopener'
|
||||||
|
|
||||||
= render partial: "layouts/mailers/signature"
|
= render partial: "layouts/mailers/signature"
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
- content_for(:title, @subject)
|
|
||||||
|
|
||||||
%h1 Bonjour,
|
|
||||||
|
|
||||||
%p
|
|
||||||
Vous avez commencé un #{@dossier_kind},
|
|
||||||
= link_to("n° #{@dossier.id}", dossier_url(@dossier))
|
|
||||||
sur la procédure « #{@dossier.procedure.libelle} ».
|
|
||||||
En raison d’un changement dans la procédure, votre #{@dossier_kind} a été inaccessible pendant quelques jours.
|
|
||||||
L’accès est à présent à nouveau possible.
|
|
||||||
|
|
||||||
%p
|
|
||||||
Malheureusement, en raison des changements dans le procédure, vous ne pourrez pas mener à terme le #{@dossier_kind} commencé.
|
|
||||||
Si votre démarche est toujours d’actualité, nous vous invitons à la recommencer sur
|
|
||||||
= link_to("la nouvelle procédure", commencer_url(@new_procedure.path))
|
|
||||||
\.
|
|
||||||
|
|
||||||
%p
|
|
||||||
Nous avons pris des mesures pour nous assurer qu’un tel désagrément ne se reproduise pas,
|
|
||||||
et vous présentons nos excuses pour la gène occasionnée.
|
|
||||||
|
|
||||||
= render partial: "layouts/mailers/signature"
|
|
|
@ -63,7 +63,7 @@
|
||||||
%ul.messages-list
|
%ul.messages-list
|
||||||
- @dossier.commentaires.with_attached_piece_jointe.each do |commentaire|
|
- @dossier.commentaires.with_attached_piece_jointe.each do |commentaire|
|
||||||
%li
|
%li
|
||||||
= render partial: "shared/dossiers/messages/message", locals: { commentaire: commentaire, connected_user: current_gestionnaire, messagerie_seen_at: nil }
|
= render partial: "shared/dossiers/messages/message", locals: { commentaire: commentaire, connected_user: current_gestionnaire, messagerie_seen_at: nil, show_reply_button: false }
|
||||||
|
|
||||||
%script{ type: "text/javascript" }
|
%script{ type: "text/javascript" }
|
||||||
window.print();
|
window.print();
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
= render partial: 'layouts/left_panels/left_panel_admin_procedurescontroller_navbar', locals: { active: 'MonAvis' }
|
|
@ -64,6 +64,10 @@
|
||||||
.procedure-list-element{ class: ('active' if active == 'Attestation') }
|
.procedure-list-element{ class: ('active' if active == 'Attestation') }
|
||||||
Attestation
|
Attestation
|
||||||
|
|
||||||
|
%a#onglet-description{ href: url_for(admin_procedure_monavis_path(@procedure)) }
|
||||||
|
.procedure-list-element{ class: ('active' if active == 'MonAvis') }
|
||||||
|
MonAvis
|
||||||
|
|
||||||
.split-hr-left
|
.split-hr-left
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
%p
|
%p
|
||||||
Bonne journée,
|
Bonne journée,
|
||||||
|
%br
|
||||||
%p
|
- if defined?(service) && service && service.nom.present?
|
||||||
L'équipe demarches-simplifiees.fr
|
= service.nom
|
||||||
|
- else
|
||||||
|
L’équipe demarches-simplifiees.fr
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
= image_tag @logo_url, height: "150", style: "display:block; max-height: 150px; max-width: 150px;"
|
= image_tag @logo_url, height: "150", style: "display:block; max-height: 150px; max-width: 150px;"
|
||||||
|
|
||||||
- content_for :footer do
|
- content_for :footer do
|
||||||
- if @dossier.present?
|
|
||||||
- messagerie_url = messagerie_dossier_url(@dossier)
|
|
||||||
- else
|
|
||||||
- messagerie_url = "#"
|
|
||||||
%strong
|
%strong
|
||||||
Merci de ne pas répondre à cet email. Pour vous adresser à votre administration, passez directement par votre
|
Merci de ne pas répondre à cet email.
|
||||||
= succeed '.' do
|
- if @dossier.present? && @dossier.messagerie_available?
|
||||||
= link_to 'messagerie', messagerie_url, target: '_blank', rel: 'noopener'
|
Pour vous adresser à votre administration, passez directement par la
|
||||||
|
= succeed '.' do
|
||||||
|
= link_to 'messagerie du dossier', messagerie_dossier_url(@dossier), target: '_blank', rel: 'noopener'
|
||||||
|
|
||||||
- if @service.present?
|
- if @service.present?
|
||||||
%table{ width: "100%", border: "0", cellspacing: "0", cellpadding: "0", style: "cursor:auto;color:#55575d;font-family:Helvetica, Arial, sans-serif;font-size:11px;line-height:22px;text-align:left;" }
|
%table{ width: "100%", border: "0", cellspacing: "0", cellpadding: "0", style: "cursor:auto;color:#55575d;font-family:Helvetica, Arial, sans-serif;font-size:11px;line-height:22px;text-align:left;" }
|
||||||
|
@ -31,7 +29,11 @@
|
||||||
%p
|
%p
|
||||||
%strong Poser une question sur votre dossier :
|
%strong Poser une question sur votre dossier :
|
||||||
%br
|
%br
|
||||||
= link_to 'Par la messagerie', messagerie_url, target: '_blank', rel: 'noopener'
|
- if @dossier.present? && @dossier.messagerie_available?
|
||||||
|
= link_to 'Par la messagerie', messagerie_dossier_url(@dossier), target: '_blank', rel: 'noopener'
|
||||||
|
- else
|
||||||
|
Par email :
|
||||||
|
= link_to @service.email, "mailto:#{@service.email}"
|
||||||
%br
|
%br
|
||||||
Par téléphone :
|
Par téléphone :
|
||||||
= link_to @service.telephone, "tel:#{@service.telephone}"
|
= link_to @service.telephone, "tel:#{@service.telephone}"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%p
|
%p
|
||||||
Bonne journée,
|
Bonne journée,
|
||||||
|
%br
|
||||||
%p --nom du service--
|
\ --nom du service--
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
%span.icon.person
|
%span.icon.person
|
||||||
%span.icon.super-admin
|
%span.icon.super-admin
|
||||||
%span.icon.mail
|
%span.icon.mail
|
||||||
|
%span.icon.reply
|
||||||
%span.icon.search
|
%span.icon.search
|
||||||
%span.icon.sign-out
|
%span.icon.sign-out
|
||||||
%span.icon.info
|
%span.icon.info
|
||||||
|
|
9
app/views/shared/_mailer_round_button.html.haml
Normal file
9
app/views/shared/_mailer_round_button.html.haml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/# From https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design
|
||||||
|
%table{ width: "100%", border: "0", cellspacing:"0", cellpadding:"0" }
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%table{ border:"0", cellspacing:"0", cellpadding:"0", style:"margin: auto" }
|
||||||
|
%tr
|
||||||
|
%td{ align:"center", style:"border-radius: 5px;", bgcolor:"#0069cc" }
|
||||||
|
%a{ href: url, target:"_blank", style:"font-size: 16px; font-family: Helvetica, Arial, sans-serif; color: #ffffff; text-decoration: none; text-decoration: none; border-radius: 5px; padding: 12px 25px; border: 1px solid #0069cc; display: inline-block;" }
|
||||||
|
= text
|
|
@ -2,7 +2,7 @@
|
||||||
%ul.messages-list
|
%ul.messages-list
|
||||||
- dossier.commentaires.with_attached_piece_jointe.each do |commentaire|
|
- dossier.commentaires.with_attached_piece_jointe.each do |commentaire|
|
||||||
%li.message{ class: commentaire_is_from_me_class(commentaire, connected_user) }
|
%li.message{ class: commentaire_is_from_me_class(commentaire, connected_user) }
|
||||||
= render partial: "shared/dossiers/messages/message", locals: { commentaire: commentaire, connected_user: connected_user, messagerie_seen_at: messagerie_seen_at }
|
= render partial: "shared/dossiers/messages/message", locals: { commentaire: commentaire, connected_user: connected_user, messagerie_seen_at: messagerie_seen_at, show_reply_button: show_reply_button(commentaire, connected_user) }
|
||||||
|
|
||||||
- if dossier.messagerie_available?
|
- if dossier.messagerie_available?
|
||||||
= render partial: "shared/dossiers/messages/form", locals: { commentaire: new_commentaire, form_url: form_url }
|
= render partial: "shared/dossiers/messages/form", locals: { commentaire: new_commentaire, form_url: form_url }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
= form_for(commentaire, url: form_url, html: { class: 'form' }) do |f|
|
= form_for(commentaire, url: form_url, html: { class: 'form' }) do |f|
|
||||||
= f.text_area :body, rows: 5, placeholder: 'Répondre ici', required: true, class: 'message-textarea'
|
= f.text_area :body, rows: 5, placeholder: 'Écrivez votre message à l’administration ici', required: true, class: 'message-textarea'
|
||||||
.flex.justify-between.wrap
|
.flex.justify-between.wrap
|
||||||
%div
|
%div
|
||||||
= f.file_field :piece_jointe, id: 'piece_jointe', direct_upload: true
|
= f.file_field :piece_jointe, id: 'piece_jointe', direct_upload: true
|
||||||
|
|
|
@ -10,11 +10,17 @@
|
||||||
= commentaire_date(commentaire)
|
= commentaire_date(commentaire)
|
||||||
.rich-text= sanitize(simple_format(commentaire.body))
|
.rich-text= sanitize(simple_format(commentaire.body))
|
||||||
|
|
||||||
- if commentaire.piece_jointe.attached?
|
.message-extras.flex.justify-start
|
||||||
.attachment-link
|
- if commentaire.piece_jointe.attached?
|
||||||
= render partial: "shared/attachment/show", locals: { attachment: commentaire.piece_jointe.attachment }
|
.attachment-link
|
||||||
- elsif commentaire.file.present?
|
= render partial: "shared/attachment/show", locals: { attachment: commentaire.piece_jointe.attachment }
|
||||||
.attachment-link
|
- elsif commentaire.file.present?
|
||||||
= link_to commentaire.file_url, class: "button", target: "_blank", rel: "noopener", title: "Télécharger" do
|
.attachment-link
|
||||||
%span.icon.attachment
|
= link_to commentaire.file_url, class: "button", target: "_blank", rel: "noopener", title: "Télécharger" do
|
||||||
= commentaire.file_identifier
|
%span.icon.attachment
|
||||||
|
= commentaire.file_identifier
|
||||||
|
|
||||||
|
- if show_reply_button
|
||||||
|
= button_tag type: 'button', class: 'button small message-answer-button', onclick: 'document.querySelector("#commentaire_body").focus()' do
|
||||||
|
%span.icon.reply
|
||||||
|
Répondre
|
||||||
|
|
|
@ -23,3 +23,4 @@
|
||||||
.flex.column.align-center
|
.flex.column.align-center
|
||||||
= link_to 'Accéder à votre dossier', dossier_path(@dossier), class: 'button large primary'
|
= link_to 'Accéder à votre dossier', dossier_path(@dossier), class: 'button large primary'
|
||||||
= link_to 'Déposer un autre dossier', procedure_lien(@dossier.procedure)
|
= link_to 'Déposer un autre dossier', procedure_lien(@dossier.procedure)
|
||||||
|
!= @dossier.procedure.monavis_embed
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
%h3.tab-title Dernier message
|
%h3.tab-title Dernier message
|
||||||
|
|
||||||
.message.inverted-background
|
.message.inverted-background
|
||||||
= render partial: "shared/dossiers/messages/message", locals: { commentaire: latest_message, connected_user: current_user, messagerie_seen_at: nil }
|
= render partial: "shared/dossiers/messages/message", locals: { commentaire: latest_message, connected_user: current_user, messagerie_seen_at: nil, show_reply_button: false }
|
||||||
|
|
||||||
= link_to commentaire_answer_action(latest_message, current_user), messagerie_dossier_url(dossier, anchor: 'new_commentaire'), class: 'button send'
|
= link_to messagerie_dossier_url(dossier, anchor: 'new_commentaire'), class: 'button send' do
|
||||||
|
%span.icon.reply
|
||||||
|
= commentaire_answer_action(latest_message, current_user)
|
||||||
|
|
|
@ -1,5 +1,24 @@
|
||||||
{
|
{
|
||||||
"ignored_warnings": [
|
"ignored_warnings": [
|
||||||
|
{
|
||||||
|
"warning_type": "Cross-Site Scripting",
|
||||||
|
"warning_code": 2,
|
||||||
|
"fingerprint": "483ae8c038244eb3ed709e89846335e2c8ff6579260348ec31d3d03d1c94ad64",
|
||||||
|
"check_name": "CrossSiteScripting",
|
||||||
|
"message": "Unescaped model attribute",
|
||||||
|
"file": "app/views/users/dossiers/merci.html.haml",
|
||||||
|
"line": 26,
|
||||||
|
"link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
|
||||||
|
"code": "current_user.dossiers.includes(:procedure).find(params[:id]).procedure.monavis_embed",
|
||||||
|
"render_path": [{"type":"controller","class":"Users::DossiersController","method":"merci","line":178,"file":"app/controllers/users/dossiers_controller.rb"}],
|
||||||
|
"location": {
|
||||||
|
"type": "template",
|
||||||
|
"template": "users/dossiers/merci"
|
||||||
|
},
|
||||||
|
"user_input": "current_user.dossiers.includes(:procedure)",
|
||||||
|
"confidence": "Weak",
|
||||||
|
"note": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"warning_type": "SQL Injection",
|
"warning_type": "SQL Injection",
|
||||||
"warning_code": 0,
|
"warning_code": 0,
|
||||||
|
@ -27,7 +46,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/procedure_presentation.rb",
|
"file": "app/models/procedure_presentation.rb",
|
||||||
"line": 97,
|
"line": 98,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "((\"self\" == \"self\") ? (dossiers) : (dossiers.includes(\"self\"))).order(\"#{self.class.sanitized_column(\"self\", column)} #{order}\")",
|
"code": "((\"self\" == \"self\") ? (dossiers) : (dossiers.includes(\"self\"))).order(\"#{self.class.sanitized_column(\"self\", column)} #{order}\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -47,7 +66,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/procedure_presentation.rb",
|
"file": "app/models/procedure_presentation.rb",
|
||||||
"line": 93,
|
"line": 94,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "dossiers.includes(((\"type_de_champ\" == \"type_de_champ\") ? (:champs) : (:champs_private))).where(\"champs.type_de_champ_id = #{column.to_i}\").order(\"champs.value #{order}\")",
|
"code": "dossiers.includes(((\"type_de_champ\" == \"type_de_champ\") ? (:champs) : (:champs_private))).where(\"champs.type_de_champ_id = #{column.to_i}\").order(\"champs.value #{order}\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -61,6 +80,6 @@
|
||||||
"note": "`column` and `order` come from the model, which is validated to prevent injection attacks. Furthermore, the sql injection attack on `column` would need to survive the `to_i`"
|
"note": "`column` and `order` come from the model, which is validated to prevent injection attacks. Furthermore, the sql injection attack on `column` would need to survive the `to_i`"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"updated": "2019-03-04 11:59:49 +0100",
|
"updated": "2019-07-17 16:03:11 +0200",
|
||||||
"brakeman_version": "4.3.1"
|
"brakeman_version": "4.3.1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,6 +206,8 @@ Rails.application.routes.draw do
|
||||||
put 'publish' => 'procedures#publish', as: :publish
|
put 'publish' => 'procedures#publish', as: :publish
|
||||||
post 'transfer' => 'procedures#transfer', as: :transfer
|
post 'transfer' => 'procedures#transfer', as: :transfer
|
||||||
put 'clone' => 'procedures#clone', as: :clone
|
put 'clone' => 'procedures#clone', as: :clone
|
||||||
|
get 'monavis' => 'procedures#monavis', as: :monavis
|
||||||
|
patch 'monavis' => 'procedures#update_monavis', as: :update_monavis
|
||||||
|
|
||||||
resource :instructeurs, only: [:show, :update]
|
resource :instructeurs, only: [:show, :update]
|
||||||
|
|
||||||
|
|
5
db/migrate/20190717132452_add_monavis_to_procedures.rb
Normal file
5
db/migrate/20190717132452_add_monavis_to_procedures.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddMonavisToProcedures < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :procedures, :monavis_embed, :text
|
||||||
|
end
|
||||||
|
end
|
|
@ -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: 2019_07_11_135457) do
|
ActiveRecord::Schema.define(version: 2019_07_17_132452) 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"
|
||||||
|
@ -500,6 +500,7 @@ ActiveRecord::Schema.define(version: 2019_07_11_135457) do
|
||||||
t.boolean "durees_conservation_required", default: true
|
t.boolean "durees_conservation_required", default: true
|
||||||
t.string "path"
|
t.string "path"
|
||||||
t.string "declarative_with_state"
|
t.string "declarative_with_state"
|
||||||
|
t.text "monavis_embed"
|
||||||
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
|
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
|
||||||
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
||||||
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
|
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
|
||||||
|
|
|
@ -49,6 +49,6 @@
|
||||||
"lint:js": "eslint ./app/javascript ./app/assets/javascripts ./config/webpack"
|
"lint:js": "eslint ./app/javascript ./app/assets/javascripts ./config/webpack"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "6.* || 8.* || >= 10.*"
|
"node": "8.* || >= 10.*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
let(:cadre_juridique) { 'cadre juridique' }
|
let(:cadre_juridique) { 'cadre juridique' }
|
||||||
let(:duree_conservation_dossiers_dans_ds) { 3 }
|
let(:duree_conservation_dossiers_dans_ds) { 3 }
|
||||||
let(:duree_conservation_dossiers_hors_ds) { 6 }
|
let(:duree_conservation_dossiers_hors_ds) { 6 }
|
||||||
|
let(:monavis_embed) { nil }
|
||||||
|
|
||||||
let(:procedure_params) {
|
let(:procedure_params) {
|
||||||
{
|
{
|
||||||
|
@ -24,7 +25,8 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
direction: direction,
|
direction: direction,
|
||||||
cadre_juridique: cadre_juridique,
|
cadre_juridique: cadre_juridique,
|
||||||
duree_conservation_dossiers_dans_ds: duree_conservation_dossiers_dans_ds,
|
duree_conservation_dossiers_dans_ds: duree_conservation_dossiers_dans_ds,
|
||||||
duree_conservation_dossiers_hors_ds: duree_conservation_dossiers_hors_ds
|
duree_conservation_dossiers_hors_ds: duree_conservation_dossiers_hors_ds,
|
||||||
|
monavis_embed: monavis_embed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,4 +747,77 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'PATCH #monavis' do
|
||||||
|
let!(:procedure) { create(:procedure, :with_type_de_champ, :with_two_type_de_piece_justificative, administrateur: admin) }
|
||||||
|
let(:procedure_params) {
|
||||||
|
{
|
||||||
|
monavis_embed: monavis_embed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context 'when administrateur is not connected' do
|
||||||
|
before do
|
||||||
|
sign_out admin
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { patch :update_monavis, params: { procedure_id: procedure.id } }
|
||||||
|
|
||||||
|
it { is_expected.to redirect_to new_user_session_path }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when administrateur is connected' do
|
||||||
|
def update_monavis
|
||||||
|
patch :update_monavis, params: { procedure_id: procedure.id, procedure: procedure_params }
|
||||||
|
procedure.reload
|
||||||
|
end
|
||||||
|
let(:monavis_embed) {
|
||||||
|
<<-MSG
|
||||||
|
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
||||||
|
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-blanc.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
||||||
|
</a>
|
||||||
|
MSG
|
||||||
|
}
|
||||||
|
|
||||||
|
context 'when all attributes are present' do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
before { update_monavis }
|
||||||
|
|
||||||
|
context 'when the embed code is valid' do
|
||||||
|
describe 'the monavis field is updated' do
|
||||||
|
subject { procedure }
|
||||||
|
|
||||||
|
it { expect(subject.monavis_embed).to eq(monavis_embed) }
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(flash[:notice]).to be_present }
|
||||||
|
it { expect(response.body).to include "MonAvis" }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the embed code is not valid' do
|
||||||
|
let(:monavis_embed) { 'invalid embed code' }
|
||||||
|
|
||||||
|
describe 'the monavis field is not updated' do
|
||||||
|
subject { procedure }
|
||||||
|
|
||||||
|
it { expect(subject.monavis_embed).to eq(nil) }
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(flash[:alert]).to be_present }
|
||||||
|
it { expect(response.body).to include "MonAvis" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when procedure is published' do
|
||||||
|
let(:procedure) { create(:procedure, :with_type_de_champ, :with_two_type_de_piece_justificative, :published, administrateur: admin) }
|
||||||
|
|
||||||
|
subject { update_monavis }
|
||||||
|
|
||||||
|
describe 'the monavis field is not updated' do
|
||||||
|
it { expect(subject.monavis_embed).to eq monavis_embed }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :with_file do
|
trait :with_file do
|
||||||
file { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'application/pdf') }
|
file { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,7 +42,7 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :with_logo do
|
trait :with_logo do
|
||||||
logo { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'application/pdf') }
|
logo { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') }
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :with_path do
|
trait :with_path do
|
||||||
|
|
|
@ -29,7 +29,7 @@ RSpec.describe DossierMailer, type: :mailer do
|
||||||
|
|
||||||
subject { described_class.notify_deletion_to_user(deleted_dossier, to_email) }
|
subject { described_class.notify_deletion_to_user(deleted_dossier, to_email) }
|
||||||
|
|
||||||
it { expect(subject.subject).to eq("Votre dossier n° #{deleted_dossier.dossier_id} a bien été supprimé") }
|
it { expect(subject.subject).to eq("Votre dossier nº #{deleted_dossier.dossier_id} a bien été supprimé") }
|
||||||
it { expect(subject.body).to include("Votre dossier") }
|
it { expect(subject.body).to include("Votre dossier") }
|
||||||
it { expect(subject.body).to include(deleted_dossier.dossier_id) }
|
it { expect(subject.body).to include(deleted_dossier.dossier_id) }
|
||||||
it { expect(subject.body).to include("a bien été supprimé") }
|
it { expect(subject.body).to include("a bien été supprimé") }
|
||||||
|
@ -41,7 +41,7 @@ RSpec.describe DossierMailer, type: :mailer do
|
||||||
|
|
||||||
subject { described_class.notify_deletion_to_administration(deleted_dossier, to_email) }
|
subject { described_class.notify_deletion_to_administration(deleted_dossier, to_email) }
|
||||||
|
|
||||||
it { expect(subject.subject).to eq("Le dossier n° #{deleted_dossier.dossier_id} a été supprimé à la demande de l'usager") }
|
it { expect(subject.subject).to eq("Le dossier nº #{deleted_dossier.dossier_id} a été supprimé à la demande de l'usager") }
|
||||||
it { expect(subject.body).to include("À la demande de l'usager") }
|
it { expect(subject.body).to include("À la demande de l'usager") }
|
||||||
it { expect(subject.body).to include(deleted_dossier.dossier_id) }
|
it { expect(subject.body).to include(deleted_dossier.dossier_id) }
|
||||||
it { expect(subject.body).to include(deleted_dossier.procedure.libelle) }
|
it { expect(subject.body).to include(deleted_dossier.procedure.libelle) }
|
||||||
|
@ -52,7 +52,7 @@ RSpec.describe DossierMailer, type: :mailer do
|
||||||
|
|
||||||
subject { described_class.notify_unhide_to_user(dossier) }
|
subject { described_class.notify_unhide_to_user(dossier) }
|
||||||
|
|
||||||
it { expect(subject.subject).to eq("Votre dossier n° #{dossier.id} n'a pas pu être supprimé") }
|
it { expect(subject.subject).to eq("Votre dossier nº #{dossier.id} n'a pas pu être supprimé") }
|
||||||
it { expect(subject.body).to include(dossier.id) }
|
it { expect(subject.body).to include(dossier.id) }
|
||||||
it { expect(subject.body).to include("n'a pas pu être supprimé") }
|
it { expect(subject.body).to include("n'a pas pu être supprimé") }
|
||||||
it { expect(subject.body).to include(dossier.procedure.libelle) }
|
it { expect(subject.body).to include(dossier.procedure.libelle) }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Preview all emails at http://localhost:3000/rails/mailers/dossier_mailer
|
# Preview all emails at http://localhost:3000/rails/mailers/dossier_mailer
|
||||||
class DossierMailerPreview < ActionMailer::Preview
|
class DossierMailerPreview < ActionMailer::Preview
|
||||||
def notify_new_draft
|
def notify_new_draft
|
||||||
DossierMailer.notify_new_draft(dossier)
|
DossierMailer.notify_new_draft(draft)
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_new_answer
|
def notify_new_answer
|
||||||
|
@ -26,11 +26,24 @@ class DossierMailerPreview < ActionMailer::Preview
|
||||||
DeletedDossier.new(dossier_id: 1, procedure: procedure)
|
DeletedDossier.new(dossier_id: 1, procedure: procedure)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def draft
|
||||||
|
Dossier.new(id: 47882, procedure: procedure, user: User.new(email: "usager@example.com"))
|
||||||
|
end
|
||||||
|
|
||||||
def dossier
|
def dossier
|
||||||
Dossier.new(id: 1, procedure: procedure, user: User.new(email: "usager@example.com"))
|
Dossier.new(id: 47882, state: :en_instruction, procedure: procedure, user: User.new(email: "usager@example.com"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure
|
def procedure
|
||||||
Procedure.new(libelle: 'Démarche pour des marches')
|
Procedure.new(libelle: 'Dotation d’Équipement des Territoires Ruraux - Exercice 2019', service: service, logo: Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def service
|
||||||
|
Service.new(
|
||||||
|
nom: 'Direction du Territoire des Vosges',
|
||||||
|
email: 'prms@ddt.vosges.gouv.fr',
|
||||||
|
telephone: '01 34 22 33 85',
|
||||||
|
horaires: 'Du lundi au vendredi, de 9 h à 18 h'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -89,7 +89,7 @@ describe MailTemplateConcern do
|
||||||
|
|
||||||
it { expect(dossier.justificatif_motivation).to be_attached }
|
it { expect(dossier.justificatif_motivation).to be_attached }
|
||||||
it { is_expected.to include("<a target=\"_blank\" rel=\"noopener\" href=\"http://localhost:3000/dossiers/#{dossier.id}/attestation\">http://localhost:3000/dossiers/#{dossier.id}/attestation</a>") }
|
it { is_expected.to include("<a target=\"_blank\" rel=\"noopener\" href=\"http://localhost:3000/dossiers/#{dossier.id}/attestation\">http://localhost:3000/dossiers/#{dossier.id}/attestation</a>") }
|
||||||
it { is_expected.to include("Télécharger le justificatif") }
|
it { is_expected.to_not include("Télécharger le justificatif") }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "in refuse mail" do
|
describe "in refuse mail" do
|
||||||
|
@ -104,6 +104,43 @@ describe MailTemplateConcern do
|
||||||
it { is_expected.to eq("--lien attestation--") }
|
it { is_expected.to eq("--lien attestation--") }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shared_examples 'inserting the --lien document justificatif-- tag' do
|
||||||
|
let(:procedure) { create(:procedure) }
|
||||||
|
|
||||||
|
subject { mail.body_for_dossier(dossier) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
mail.body = "--lien document justificatif--"
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'without justificatif' do
|
||||||
|
it { is_expected.to include("[l'instructeur n'a pas joint de document supplémentaire]") }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'with justificatif' do
|
||||||
|
before do
|
||||||
|
dossier.justificatif_motivation.attach(justificatif)
|
||||||
|
end
|
||||||
|
it { expect(dossier.justificatif_motivation).to be_attached }
|
||||||
|
it { is_expected.to include("Télécharger le document justificatif") }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'in closed mail' do
|
||||||
|
let(:mail) { create(:closed_mail, procedure: procedure) }
|
||||||
|
it_behaves_like 'inserting the --lien document justificatif-- tag'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'in refused mail' do
|
||||||
|
let(:mail) { create(:refused_mail, procedure: procedure) }
|
||||||
|
it_behaves_like 'inserting the --lien document justificatif-- tag'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'in without continuation mail' do
|
||||||
|
let(:mail) { create(:without_continuation_mail, procedure: procedure) }
|
||||||
|
it_behaves_like 'inserting the --lien document justificatif-- tag'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#replace_tags' do
|
describe '#replace_tags' do
|
||||||
|
|
|
@ -449,7 +449,7 @@ describe Dossier do
|
||||||
end.to change(ActionMailer::Base.deliveries, :size).from(0).to(1)
|
end.to change(ActionMailer::Base.deliveries, :size).from(0).to(1)
|
||||||
|
|
||||||
mail = ActionMailer::Base.deliveries.last
|
mail = ActionMailer::Base.deliveries.last
|
||||||
expect(mail.subject).to eq("Retrouvez votre brouillon pour la démarche \"#{procedure.libelle}\"")
|
expect(mail.subject).to eq("Retrouvez votre brouillon pour la démarche « #{procedure.libelle} »")
|
||||||
expect(mail.html_part.body).to include(dossier_url(dossier))
|
expect(mail.html_part.body).to include(dossier_url(dossier))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,43 @@ describe Procedure do
|
||||||
it { expect(procedure.valid?).to eq(true) }
|
it { expect(procedure.valid?).to eq(true) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'monavis' do
|
||||||
|
context 'nil is allowed' do
|
||||||
|
it { is_expected.to allow_value(nil).for(:monavis_embed) }
|
||||||
|
it { is_expected.to allow_value('').for(:monavis_embed) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'random string is not allowed' do
|
||||||
|
let(:procedure) { build(:procedure, monavis_embed: "plop") }
|
||||||
|
it { expect(procedure.valid?).to eq(false) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'random html is not allowed' do
|
||||||
|
let(:procedure) { build(:procedure, monavis_embed: '<img src="http://some.analytics/hello.gif">') }
|
||||||
|
it { expect(procedure.valid?).to eq(false) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Monavis embed code with white button is allowed' do
|
||||||
|
monavis_blanc = <<-MSG
|
||||||
|
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
||||||
|
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-blanc.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
||||||
|
</a>
|
||||||
|
MSG
|
||||||
|
let(:procedure) { build(:procedure, monavis_embed: monavis_blanc) }
|
||||||
|
it { expect(procedure.valid?).to eq(true) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Monavis embed code with blue button is allowed' do
|
||||||
|
monavis_bleu = <<-MSG
|
||||||
|
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
||||||
|
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-bleu.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
||||||
|
</a>
|
||||||
|
MSG
|
||||||
|
let(:procedure) { build(:procedure, monavis_embed: monavis_bleu) }
|
||||||
|
it { expect(procedure.valid?).to eq(true) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
shared_examples 'duree de conservation' do
|
shared_examples 'duree de conservation' do
|
||||||
context 'duree_conservation_required it true, the field gets validated' do
|
context 'duree_conservation_required it true, the field gets validated' do
|
||||||
before { subject.durees_conservation_required = true }
|
before { subject.durees_conservation_required = true }
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
describe 'shared/dossiers/messages/message.html.haml', type: :view do
|
describe 'shared/dossiers/messages/message.html.haml', type: :view do
|
||||||
before { view.extend DossierHelper }
|
before { view.extend DossierHelper }
|
||||||
|
|
||||||
subject { render 'shared/dossiers/messages/message.html.haml', commentaire: commentaire, messagerie_seen_at: seen_at, connected_user: dossier.user }
|
subject { render 'shared/dossiers/messages/message.html.haml', commentaire: commentaire, messagerie_seen_at: seen_at, connected_user: dossier.user, show_reply_button: true }
|
||||||
|
|
||||||
let(:dossier) { create(:dossier, :en_construction) }
|
let(:dossier) { create(:dossier, :en_construction) }
|
||||||
let(:commentaire) { create(:commentaire, dossier: dossier) }
|
let(:commentaire) { create(:commentaire, dossier: dossier) }
|
||||||
let(:seen_at) { commentaire.created_at + 1.hour }
|
let(:seen_at) { commentaire.created_at + 1.hour }
|
||||||
|
|
||||||
|
it { is_expected.to have_button("Répondre") }
|
||||||
|
|
||||||
context "with a seen_at after commentaire created_at" do
|
context "with a seen_at after commentaire created_at" do
|
||||||
let(:seen_at) { commentaire.created_at + 1.hour }
|
let(:seen_at) { commentaire.created_at + 1.hour }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue