Merge branch 'dev'
This commit is contained in:
commit
9c0fa30d5b
39 changed files with 538 additions and 342 deletions
1
Gemfile
1
Gemfile
|
@ -33,7 +33,6 @@ gem 'haml-rails'
|
||||||
gem 'bootstrap-sass', '~> 3.3.5'
|
gem 'bootstrap-sass', '~> 3.3.5'
|
||||||
|
|
||||||
# Pagination
|
# Pagination
|
||||||
gem 'will_paginate-bootstrap'
|
|
||||||
gem 'kaminari'
|
gem 'kaminari'
|
||||||
|
|
||||||
# Decorators
|
# Decorators
|
||||||
|
|
|
@ -682,9 +682,6 @@ GEM
|
||||||
websocket-driver (0.6.5)
|
websocket-driver (0.6.5)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.2)
|
websocket-extensions (0.1.2)
|
||||||
will_paginate (3.1.5)
|
|
||||||
will_paginate-bootstrap (1.0.1)
|
|
||||||
will_paginate (>= 3.0.3)
|
|
||||||
xml-simple (1.1.5)
|
xml-simple (1.1.5)
|
||||||
xpath (2.1.0)
|
xpath (2.1.0)
|
||||||
nokogiri (~> 1.3)
|
nokogiri (~> 1.3)
|
||||||
|
@ -779,7 +776,6 @@ DEPENDENCIES
|
||||||
vcr
|
vcr
|
||||||
web-console
|
web-console
|
||||||
webmock
|
webmock
|
||||||
will_paginate-bootstrap
|
|
||||||
xray-rails
|
xray-rails
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
|
|
17
README.md
17
README.md
|
@ -14,6 +14,9 @@ Téléprocédures Simplifiées, ou TPS pour les intimes, est une plateforme 100
|
||||||
### Développement
|
### Développement
|
||||||
|
|
||||||
- Mailcatcher : `gem install mailcatcher`
|
- Mailcatcher : `gem install mailcatcher`
|
||||||
|
- Hivemind :
|
||||||
|
* Mac : `brew install hivemind`
|
||||||
|
* Linux : voir https://github.com/DarthSim/hivemind#installation
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
|
@ -68,6 +71,8 @@ client_id: ''
|
||||||
client_secret: ''
|
client_secret: ''
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*Note : les valeurs pour ces deux paramètres sont renseignées dans le Keepass*
|
||||||
|
|
||||||
## Création des comptes initiaux
|
## Création des comptes initiaux
|
||||||
|
|
||||||
rails c
|
rails c
|
||||||
|
@ -81,7 +86,6 @@ client_secret: ''
|
||||||
|
|
||||||
## Lancement de l'application
|
## Lancement de l'application
|
||||||
|
|
||||||
brew install hivemind # Avec Linux voir https://github.com/DarthSim/hivemind#installation
|
|
||||||
hivemind
|
hivemind
|
||||||
|
|
||||||
## Programmation des jobs
|
## Programmation des jobs
|
||||||
|
@ -125,3 +129,14 @@ Pour exécuter les tests de l'application, plusieurs possibilités :
|
||||||
|
|
||||||
bundle binstub railties --force
|
bundle binstub railties --force
|
||||||
rake rails:update:bin
|
rake rails:update:bin
|
||||||
|
|
||||||
|
## Tâches Super Admin
|
||||||
|
|
||||||
|
- ajouter un compte super admin :
|
||||||
|
`bundle exec rake admin:create_admin[email-du-compte-github@exemple.com]`
|
||||||
|
|
||||||
|
- lister les comptes super admin :
|
||||||
|
`bundle exec rake admin:list`
|
||||||
|
|
||||||
|
- supprimer un compte super admin :
|
||||||
|
`bundle exec rake admin:delete_admin[email-du-compte-github@exemple.com]`
|
||||||
|
|
|
@ -7,7 +7,7 @@ class API::V1::DossiersController < APIController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
||||||
dossiers = procedure.dossiers.state_not_brouillon.paginate(page: params[:page])
|
dossiers = procedure.dossiers.state_not_brouillon.page(params[:page]).per(per_page)
|
||||||
|
|
||||||
render json: { dossiers: dossiers.map{ |dossier| DossiersSerializer.new(dossier) }, pagination: pagination(dossiers) }, status: 200
|
render json: { dossiers: dossiers.map{ |dossier| DossiersSerializer.new(dossier) }, pagination: pagination(dossiers) }, status: 200
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
@ -35,8 +35,12 @@ class API::V1::DossiersController < APIController
|
||||||
def pagination(dossiers)
|
def pagination(dossiers)
|
||||||
{
|
{
|
||||||
page: dossiers.current_page,
|
page: dossiers.current_page,
|
||||||
resultats_par_page: dossiers.per_page,
|
resultats_par_page: dossiers.limit_value,
|
||||||
nombre_de_page: dossiers.total_pages
|
nombre_de_page: dossiers.total_pages
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def per_page # inherited value from will_paginate
|
||||||
|
12
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -123,8 +123,8 @@ class Backoffice::DossiersController < Backoffice::DossiersListController
|
||||||
notice = "Dossier considéré comme sans suite."
|
notice = "Dossier considéré comme sans suite."
|
||||||
template = dossier.procedure.without_continuation_mail_template
|
template = dossier.procedure.without_continuation_mail_template
|
||||||
when "close"
|
when "close"
|
||||||
dossier.attestation = dossier.build_attestation
|
|
||||||
dossier.accepte!
|
dossier.accepte!
|
||||||
|
dossier.attestation = dossier.build_attestation
|
||||||
notice = "Dossier traité avec succès."
|
notice = "Dossier traité avec succès."
|
||||||
template = dossier.procedure.closed_mail_template
|
template = dossier.procedure.closed_mail_template
|
||||||
end
|
end
|
||||||
|
|
|
@ -89,8 +89,8 @@ module NewGestionnaire
|
||||||
notice = "Dossier considéré comme sans suite."
|
notice = "Dossier considéré comme sans suite."
|
||||||
template = procedure.without_continuation_mail_template
|
template = procedure.without_continuation_mail_template
|
||||||
when "accepter"
|
when "accepter"
|
||||||
dossier.attestation = dossier.build_attestation
|
|
||||||
dossier.accepte!
|
dossier.accepte!
|
||||||
|
dossier.attestation = dossier.build_attestation
|
||||||
notice = "Dossier traité avec succès."
|
notice = "Dossier traité avec succès."
|
||||||
template = procedure.closed_mail_template
|
template = procedure.closed_mail_template
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class DossierDecorator < Draper::Decorator
|
class DossierDecorator < Draper::Decorator
|
||||||
include Rails.application.routes.url_helpers
|
include Rails.application.routes.url_helpers
|
||||||
|
|
||||||
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
|
delegate :current_page, :limit_value, :total_pages
|
||||||
delegate_all
|
delegate_all
|
||||||
|
|
||||||
def first_creation
|
def first_creation
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
class DossiersDecorator < Draper::CollectionDecorator
|
class DossiersDecorator < Draper::CollectionDecorator
|
||||||
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
|
delegate :current_page, :limit_value, :total_pages
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
class ProceduresDecorator < Draper::CollectionDecorator
|
class ProceduresDecorator < Draper::CollectionDecorator
|
||||||
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
|
delegate :current_page, :limit_value, :total_pages
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class AttestationTemplate < ApplicationRecord
|
class AttestationTemplate < ApplicationRecord
|
||||||
include ActionView::Helpers::NumberHelper
|
include ActionView::Helpers::NumberHelper
|
||||||
|
include TagsSubstitutionConcern
|
||||||
|
|
||||||
belongs_to :procedure
|
belongs_to :procedure
|
||||||
|
|
||||||
|
@ -11,16 +12,6 @@ class AttestationTemplate < ApplicationRecord
|
||||||
|
|
||||||
FILE_MAX_SIZE_IN_MB = 0.5
|
FILE_MAX_SIZE_IN_MB = 0.5
|
||||||
|
|
||||||
def tags
|
|
||||||
if procedure.for_individual?
|
|
||||||
identity_tags = individual_tags
|
|
||||||
else
|
|
||||||
identity_tags = entreprise_tags + etablissement_tags
|
|
||||||
end
|
|
||||||
|
|
||||||
identity_tags + dossier_tags + procedure_type_de_champ_public_private_tags
|
|
||||||
end
|
|
||||||
|
|
||||||
def attestation_for(dossier)
|
def attestation_for(dossier)
|
||||||
Attestation.new(title: replace_tags(title, dossier), pdf: build_pdf(dossier))
|
Attestation.new(title: replace_tags(title, dossier), pdf: build_pdf(dossier))
|
||||||
end
|
end
|
||||||
|
@ -53,33 +44,6 @@ class AttestationTemplate < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure_type_de_champ_public_private_tags
|
|
||||||
(procedure.types_de_champ + procedure.types_de_champ_private)
|
|
||||||
.map { |tdc| { libelle: tdc.libelle, description: tdc.description } }
|
|
||||||
end
|
|
||||||
|
|
||||||
def dossier_tags
|
|
||||||
[{ libelle: 'motivation', description: '', target: 'motivation' },
|
|
||||||
{ libelle: 'numéro du dossier', description: '', target: 'id' }]
|
|
||||||
end
|
|
||||||
|
|
||||||
def individual_tags
|
|
||||||
[{ libelle: 'civilité', description: 'M., Mme', target: 'gender' },
|
|
||||||
{ libelle: 'nom', description: "nom de l'usager", target: 'nom' },
|
|
||||||
{ libelle: 'prénom', description: "prénom de l'usager", target: 'prenom' }]
|
|
||||||
end
|
|
||||||
|
|
||||||
def entreprise_tags
|
|
||||||
[{ libelle: 'SIREN', description: '', target: 'siren' },
|
|
||||||
{ libelle: 'numéro de TVA intracommunautaire', description: '', target: 'numero_tva_intracommunautaire' },
|
|
||||||
{ libelle: 'SIRET du siège social', description: '', target: 'siret_siege_social' },
|
|
||||||
{ libelle: 'raison sociale', description: '', target: 'raison_sociale' }]
|
|
||||||
end
|
|
||||||
|
|
||||||
def etablissement_tags
|
|
||||||
[{ libelle: 'adresse', description: '', target: 'inline_adresse' }]
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_pdf(dossier)
|
def build_pdf(dossier)
|
||||||
action_view = ActionView::Base.new(ActionController::Base.view_paths,
|
action_view = ActionView::Base.new(ActionController::Base.view_paths,
|
||||||
logo: logo,
|
logo: logo,
|
||||||
|
@ -104,51 +68,4 @@ class AttestationTemplate < ApplicationRecord
|
||||||
|
|
||||||
pdf
|
pdf
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_tags(text, dossier)
|
|
||||||
if text.nil?
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
|
|
||||||
text = replace_type_de_champ_tags(text, procedure.types_de_champ, dossier.champs)
|
|
||||||
text = replace_type_de_champ_tags(text, procedure.types_de_champ_private, dossier.champs_private)
|
|
||||||
|
|
||||||
tags_and_datas = [
|
|
||||||
[dossier_tags, dossier],
|
|
||||||
[individual_tags, dossier.individual],
|
|
||||||
[entreprise_tags, dossier.entreprise],
|
|
||||||
[etablissement_tags, dossier.entreprise&.etablissement]]
|
|
||||||
|
|
||||||
tags_and_datas.inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def replace_type_de_champ_tags(text, types_de_champ, dossier_champs)
|
|
||||||
types_de_champ.inject(text) do |acc, tag|
|
|
||||||
champ = dossier_champs
|
|
||||||
.select { |dossier_champ| dossier_champ.libelle == tag[:libelle] }
|
|
||||||
.first
|
|
||||||
|
|
||||||
replace_tag(acc, tag, champ)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def replace_tags_with_values_from_data(text, tags, data)
|
|
||||||
if data.present?
|
|
||||||
tags.inject(text) do |acc, tag|
|
|
||||||
replace_tag(acc, tag, data.send(tag[:target].to_sym))
|
|
||||||
end
|
|
||||||
else
|
|
||||||
text
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def replace_tag(text, tag, value)
|
|
||||||
libelle = Regexp.quote(tag[:libelle])
|
|
||||||
|
|
||||||
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
|
||||||
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
|
||||||
libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]")
|
|
||||||
|
|
||||||
text.gsub(/--#{libelle}--/, value.to_s)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,28 +3,7 @@ module MailTemplateConcern
|
||||||
|
|
||||||
include Rails.application.routes.url_helpers
|
include Rails.application.routes.url_helpers
|
||||||
include ActionView::Helpers::UrlHelper
|
include ActionView::Helpers::UrlHelper
|
||||||
|
include TagsSubstitutionConcern
|
||||||
TAGS = []
|
|
||||||
TAGS << TAG_NUMERO_DOSSIER = {
|
|
||||||
name: "numero_dossier",
|
|
||||||
description: "Permet d'afficher le numéro de dossier de l'utilisateur."
|
|
||||||
}
|
|
||||||
TAGS << TAG_LIEN_DOSSIER = {
|
|
||||||
name: "lien_dossier",
|
|
||||||
description: "Permet d'afficher un lien vers le dossier de l'utilisateur."
|
|
||||||
}
|
|
||||||
TAGS << TAG_LIBELLE_PROCEDURE = {
|
|
||||||
name: "libelle_procedure",
|
|
||||||
description: "Permet d'afficher le libellé de la procédure."
|
|
||||||
}
|
|
||||||
TAGS << TAG_DATE_DE_DECISION = {
|
|
||||||
name: "date_de_decision",
|
|
||||||
description: "Permet d'afficher la date à laquelle la décision finale (acceptation, refus, classement sans suite) sur le dossier a été prise."
|
|
||||||
}
|
|
||||||
TAGS << TAG_MOTIVATION = {
|
|
||||||
name: "motivation",
|
|
||||||
description: "Permet d'afficher la motivation associée à la décision finale (acceptation, refus, classement sans suite) sur le dossier. Attention, elle est facultative."
|
|
||||||
}
|
|
||||||
|
|
||||||
def object_for_dossier(dossier)
|
def object_for_dossier(dossier)
|
||||||
replace_tags(object, dossier)
|
replace_tags(object, dossier)
|
||||||
|
@ -34,35 +13,35 @@ module MailTemplateConcern
|
||||||
replace_tags(body, dossier)
|
replace_tags(body, dossier)
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_tags(string, dossier)
|
# TODO: remove legacy argument when removing legacy tags
|
||||||
TAGS.inject(string) do |acc, tag|
|
def tags(reject_legacy: true, is_dossier_termine: self.class.const_get(:IS_DOSSIER_TERMINE))
|
||||||
acc.gsub("--#{tag[:name]}--", replace_tag(tag, dossier)) || acc
|
super(is_dossier_termine: is_dossier_termine)
|
||||||
end
|
.reject { |tag| reject_legacy && tag[:is_legacy] }
|
||||||
end
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def default
|
def default_for_procedure(procedure)
|
||||||
body = ActionController::Base.new.render_to_string(template: self.const_get(:TEMPLATE_NAME))
|
body = ActionController::Base.new.render_to_string(template: self.const_get(:TEMPLATE_NAME))
|
||||||
self.new(object: self.const_get(:DEFAULT_OBJECT), body: body)
|
self.new(object: self.const_get(:DEFAULT_OBJECT), body: body, procedure: procedure)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def replace_tag(tag, dossier)
|
def dossier_tags
|
||||||
case tag
|
super +
|
||||||
when TAG_NUMERO_DOSSIER
|
[{ libelle: 'lien dossier', description: '', lambda: -> (d) { users_dossier_recapitulatif_link(d) } },
|
||||||
dossier.id.to_s
|
# TODO: remove legacy tags
|
||||||
when TAG_LIEN_DOSSIER
|
{ libelle: 'numero_dossier', description: '', target: :id, is_legacy: true },
|
||||||
link_to users_dossier_recapitulatif_url(dossier), users_dossier_recapitulatif_url(dossier), target: '_blank'
|
{ libelle: 'lien_dossier', description: '', lambda: -> (d) { users_dossier_recapitulatif_link(d) }, is_legacy: true },
|
||||||
when TAG_LIBELLE_PROCEDURE
|
{ libelle: 'libelle_procedure', description: '', lambda: -> (d) { d.procedure.libelle }, is_legacy: true },
|
||||||
dossier.procedure.libelle
|
{ libelle: 'date_de_decision', description: '',
|
||||||
when TAG_DATE_DE_DECISION
|
lambda: -> (d) { d.processed_at.present? ? d.processed_at.localtime.strftime('%d/%m/%Y') : '' },
|
||||||
dossier.processed_at.present? ? dossier.processed_at.localtime.strftime("%d/%m/%Y") : ""
|
dossier_termine_only: true, is_legacy: true }]
|
||||||
when TAG_MOTIVATION
|
end
|
||||||
dossier.motivation || ""
|
|
||||||
else
|
def users_dossier_recapitulatif_link(dossier)
|
||||||
'--BALISE_NON_RECONNUE--'
|
url = users_dossier_recapitulatif_url(dossier)
|
||||||
end
|
link_to(url, url, target: '_blank')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
113
app/models/concerns/tags_substitution_concern.rb
Normal file
113
app/models/concerns/tags_substitution_concern.rb
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
module TagsSubstitutionConcern
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def tags(is_dossier_termine: true)
|
||||||
|
if procedure.for_individual?
|
||||||
|
identity_tags = individual_tags
|
||||||
|
else
|
||||||
|
identity_tags = entreprise_tags + etablissement_tags
|
||||||
|
end
|
||||||
|
|
||||||
|
tags = identity_tags + dossier_tags + procedure_type_de_champ_public_private_tags
|
||||||
|
filter_tags(tags, is_dossier_termine)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def filter_tags(tags, is_dossier_termine)
|
||||||
|
if !is_dossier_termine
|
||||||
|
tags.reject { |tag| tag[:dossier_termine_only] }
|
||||||
|
else
|
||||||
|
tags
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def procedure_type_de_champ_public_private_tags
|
||||||
|
(procedure.types_de_champ + procedure.types_de_champ_private)
|
||||||
|
.map { |tdc| { libelle: tdc.libelle, description: tdc.description } }
|
||||||
|
end
|
||||||
|
|
||||||
|
def dossier_tags
|
||||||
|
[{ libelle: 'motivation',
|
||||||
|
description: 'Motivation facultative associée à la décision finale d’acceptation, refus ou classement sans suite',
|
||||||
|
target: :motivation,
|
||||||
|
dossier_termine_only: true },
|
||||||
|
{ libelle: 'date de décision',
|
||||||
|
description: 'Date de la décision d’acceptation, refus, ou classement sans suite',
|
||||||
|
lambda: -> (d) { d.processed_at.present? ? d.processed_at.localtime.strftime('%d/%m/%Y') : '' },
|
||||||
|
dossier_termine_only: true },
|
||||||
|
{ libelle: 'libellé procédure', description: '', lambda: -> (d) { d.procedure.libelle } },
|
||||||
|
{ libelle: 'numéro du dossier', description: '', target: :id }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def individual_tags
|
||||||
|
[{ libelle: 'civilité', description: 'M., Mme', target: :gender },
|
||||||
|
{ libelle: 'nom', description: "nom de l'usager", target: :nom },
|
||||||
|
{ libelle: 'prénom', description: "prénom de l'usager", target: :prenom }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def entreprise_tags
|
||||||
|
[{ libelle: 'SIREN', description: '', target: :siren },
|
||||||
|
{ libelle: 'numéro de TVA intracommunautaire', description: '', target: :numero_tva_intracommunautaire },
|
||||||
|
{ libelle: 'SIRET du siège social', description: '', target: :siret_siege_social },
|
||||||
|
{ libelle: 'raison sociale', description: '', target: :raison_sociale }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def etablissement_tags
|
||||||
|
[{ libelle: 'adresse', description: '', target: :inline_adresse }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_tags(text, dossier)
|
||||||
|
if text.nil?
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
|
||||||
|
text = replace_type_de_champ_tags(text, procedure.types_de_champ, dossier.champs)
|
||||||
|
text = replace_type_de_champ_tags(text, procedure.types_de_champ_private, dossier.champs_private)
|
||||||
|
|
||||||
|
tags_and_datas = [
|
||||||
|
[dossier_tags, dossier],
|
||||||
|
[individual_tags, dossier.individual],
|
||||||
|
[entreprise_tags, dossier.entreprise],
|
||||||
|
[etablissement_tags, dossier.entreprise&.etablissement]]
|
||||||
|
|
||||||
|
tags_and_datas
|
||||||
|
.map { |(tags, data)| [filter_tags(tags, dossier.termine?), data] }
|
||||||
|
.inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_type_de_champ_tags(text, types_de_champ, dossier_champs)
|
||||||
|
types_de_champ.inject(text) do |acc, tag|
|
||||||
|
champ = dossier_champs
|
||||||
|
.select { |dossier_champ| dossier_champ.libelle == tag[:libelle] }
|
||||||
|
.first
|
||||||
|
|
||||||
|
replace_tag(acc, tag, champ)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_tags_with_values_from_data(text, tags, data)
|
||||||
|
if data.present?
|
||||||
|
tags.inject(text) do |acc, tag|
|
||||||
|
if tag.key?(:target)
|
||||||
|
value = data.send(tag[:target])
|
||||||
|
else
|
||||||
|
value = tag[:lambda].(data)
|
||||||
|
end
|
||||||
|
replace_tag(acc, tag, value)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
text
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_tag(text, tag, value)
|
||||||
|
libelle = Regexp.quote(tag[:libelle])
|
||||||
|
|
||||||
|
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
||||||
|
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
||||||
|
libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]")
|
||||||
|
|
||||||
|
text.gsub(/--#{libelle}--/, value.to_s)
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,10 +2,12 @@ module Mails
|
||||||
class ClosedMail < ApplicationRecord
|
class ClosedMail < ApplicationRecord
|
||||||
include MailTemplateConcern
|
include MailTemplateConcern
|
||||||
|
|
||||||
|
belongs_to :procedure
|
||||||
|
|
||||||
SLUG = "closed_mail"
|
SLUG = "closed_mail"
|
||||||
TEMPLATE_NAME = "mails/closed_mail"
|
TEMPLATE_NAME = "mails/closed_mail"
|
||||||
DISPLAYED_NAME = "Accusé d'acceptation"
|
DISPLAYED_NAME = "Accusé d'acceptation"
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été accepté'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numéro du dossier-- a été accepté'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION, TAG_MOTIVATION]
|
IS_DOSSIER_TERMINE = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,12 @@ module Mails
|
||||||
class InitiatedMail < ApplicationRecord
|
class InitiatedMail < ApplicationRecord
|
||||||
include MailTemplateConcern
|
include MailTemplateConcern
|
||||||
|
|
||||||
|
belongs_to :procedure
|
||||||
|
|
||||||
SLUG = "initiated_mail"
|
SLUG = "initiated_mail"
|
||||||
TEMPLATE_NAME = "mails/initiated_mail"
|
TEMPLATE_NAME = "mails/initiated_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de réception'
|
DISPLAYED_NAME = 'Accusé de réception'
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a bien été reçu'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numéro du dossier-- a bien été reçu'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE]
|
IS_DOSSIER_TERMINE = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,12 @@ module Mails
|
||||||
class ReceivedMail < ApplicationRecord
|
class ReceivedMail < ApplicationRecord
|
||||||
include MailTemplateConcern
|
include MailTemplateConcern
|
||||||
|
|
||||||
|
belongs_to :procedure
|
||||||
|
|
||||||
SLUG = "received_mail"
|
SLUG = "received_mail"
|
||||||
TEMPLATE_NAME = "mails/received_mail"
|
TEMPLATE_NAME = "mails/received_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de passage en instruction'
|
DISPLAYED_NAME = 'Accusé de passage en instruction'
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- va être instruit'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numéro du dossier-- va être instruit'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE]
|
IS_DOSSIER_TERMINE = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,12 @@ module Mails
|
||||||
class RefusedMail < ApplicationRecord
|
class RefusedMail < ApplicationRecord
|
||||||
include MailTemplateConcern
|
include MailTemplateConcern
|
||||||
|
|
||||||
|
belongs_to :procedure
|
||||||
|
|
||||||
SLUG = "refused_mail"
|
SLUG = "refused_mail"
|
||||||
TEMPLATE_NAME = "mails/refused_mail"
|
TEMPLATE_NAME = "mails/refused_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de rejet du dossier'
|
DISPLAYED_NAME = 'Accusé de rejet du dossier'
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été refusé'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numéro du dossier-- a été refusé'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION, TAG_MOTIVATION]
|
IS_DOSSIER_TERMINE = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,12 @@ module Mails
|
||||||
class WithoutContinuationMail < ApplicationRecord
|
class WithoutContinuationMail < ApplicationRecord
|
||||||
include MailTemplateConcern
|
include MailTemplateConcern
|
||||||
|
|
||||||
|
belongs_to :procedure
|
||||||
|
|
||||||
SLUG = "without_continuation"
|
SLUG = "without_continuation"
|
||||||
TEMPLATE_NAME = "mails/without_continuation_mail"
|
TEMPLATE_NAME = "mails/without_continuation_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de classement sans suite'
|
DISPLAYED_NAME = 'Accusé de classement sans suite'
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été classé sans suite'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numéro du dossier-- a été classé sans suite'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION, TAG_MOTIVATION]
|
IS_DOSSIER_TERMINE = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -167,23 +167,23 @@ class Procedure < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def initiated_mail_template
|
def initiated_mail_template
|
||||||
initiated_mail || Mails::InitiatedMail.default
|
initiated_mail || Mails::InitiatedMail.default_for_procedure(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def received_mail_template
|
def received_mail_template
|
||||||
received_mail || Mails::ReceivedMail.default
|
received_mail || Mails::ReceivedMail.default_for_procedure(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def closed_mail_template
|
def closed_mail_template
|
||||||
closed_mail || Mails::ClosedMail.default
|
closed_mail || Mails::ClosedMail.default_for_procedure(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def refused_mail_template
|
def refused_mail_template
|
||||||
refused_mail || Mails::RefusedMail.default
|
refused_mail || Mails::RefusedMail.default_for_procedure(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def without_continuation_mail_template
|
def without_continuation_mail_template
|
||||||
without_continuation_mail || Mails::WithoutContinuationMail.default
|
without_continuation_mail || Mails::WithoutContinuationMail.default_for_procedure(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fields
|
def fields
|
||||||
|
|
|
@ -22,9 +22,9 @@
|
||||||
Balise
|
Balise
|
||||||
%th
|
%th
|
||||||
Description
|
Description
|
||||||
- @mail_template.class.const_get(:ALLOWED_TAGS).each do |tag|
|
- @mail_template.tags.each do |tag|
|
||||||
%tr
|
%tr
|
||||||
%td.center
|
%td.center
|
||||||
= "--#{tag[:name]}--"
|
= "--#{tag[:libelle]}--"
|
||||||
%td
|
%td
|
||||||
= tag[:description]
|
= tag[:description]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
Bonjour,
|
Bonjour,
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Votre dossier nº --numero_dossier-- a été accepté le --date_de_decision--.
|
Votre dossier nº --numéro du dossier-- a été accepté le --date de décision--.
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
A tout moment, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien_dossier--
|
A tout moment, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien dossier--
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Bonne journée,
|
Bonne journée,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
Bonjour,
|
Bonjour,
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Votre administration vous confirme la bonne réception de votre dossier nº --numero_dossier--.
|
Votre administration vous confirme la bonne réception de votre dossier nº --numéro du dossier--.
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
A tout moment, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien_dossier--
|
A tout moment, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien dossier--
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Bonne journée,
|
Bonne journée,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Bonjour,
|
Bonjour,
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Votre administration vous confirme la bonne réception de votre dossier nº --numero_dossier--. Celui-ci sera instruit dans le délai légal déclaré par votre interlocuteur.
|
Votre administration vous confirme la bonne réception de votre dossier nº --numéro du dossier--. Celui-ci sera instruit dans le délai légal déclaré par votre interlocuteur.
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Bonne journée,
|
Bonne journée,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
Bonjour,
|
Bonjour,
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Votre dossier nº --numero_dossier-- a été refusé le --date_de_decision--.
|
Votre dossier nº --numéro du dossier-- a été refusé le --date de décision--.
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Pour en savoir plus sur le motif du refus, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien_dossier--
|
Pour en savoir plus sur le motif du refus, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien dossier--
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Bonne journée,
|
Bonne journée,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
Bonjour,
|
Bonjour,
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Votre dossier nº --numero_dossier-- a été classé sans suite le --date_de_decision--.
|
Votre dossier nº --numéro du dossier-- a été classé sans suite le --date de décision--.
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Pour en savoir plus sur les raisons de ce classement sans suite, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien_dossier--
|
Pour en savoir plus sur les raisons de ce classement sans suite, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : --lien dossier--
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
Bonne journée,
|
Bonne journée,
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
require 'will_paginate'
|
|
||||||
|
|
||||||
WillPaginate.per_page = 12
|
|
|
@ -26,9 +26,6 @@ fr:
|
||||||
no-commentaires: "Il n'y a aucun message dans le fil de discussion, n'hésitez pas à initier le premier."
|
no-commentaires: "Il n'y a aucun message dans le fil de discussion, n'hésitez pas à initier le premier."
|
||||||
depositaire: "Dépositaire"
|
depositaire: "Dépositaire"
|
||||||
pieces: "Pièces jointes"
|
pieces: "Pièces jointes"
|
||||||
will_paginate:
|
|
||||||
next_label: 'Suivant'
|
|
||||||
previous_label: 'Précédent'
|
|
||||||
views:
|
views:
|
||||||
pagination:
|
pagination:
|
||||||
next: Suivant
|
next: Suivant
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
namespace :'2017_12_21_replace_deprecated_mail_template_tags' do
|
||||||
|
task set: :environment do
|
||||||
|
replace_tag('numero_dossier', 'numéro du dossier')
|
||||||
|
replace_tag('date_de_decision', 'date de décision')
|
||||||
|
replace_tag('libelle_procedure', 'libellé procédure')
|
||||||
|
replace_tag('lien_dossier', 'lien dossier')
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_tag(old_tag, new_tag)
|
||||||
|
mails = [ Mails::ClosedMail, Mails::InitiatedMail, Mails::ReceivedMail, Mails::RefusedMail, Mails::WithoutContinuationMail]
|
||||||
|
mails.each do |mail|
|
||||||
|
replace_tag_in(mail, 'object', old_tag, new_tag)
|
||||||
|
replace_tag_in(mail, 'body', old_tag, new_tag)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_tag_in(mail, field, old_tag, new_tag)
|
||||||
|
mail
|
||||||
|
.where("#{field} LIKE ?", "%#{old_tag}%")
|
||||||
|
.update_all("#{field} = REPLACE(#{field}, '#{old_tag}', '#{new_tag}')")
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,4 +9,19 @@ namespace :admin do
|
||||||
puts "An error occured : #{a.errors.full_messages}"
|
puts "An error occured : #{a.errors.full_messages}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
task list: :environment do
|
||||||
|
puts "All Administrations :"
|
||||||
|
Administration.all.pluck(:email).each do |a|
|
||||||
|
puts a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
task :delete_admin, [:email] => :environment do |t, args|
|
||||||
|
email = args[:email]
|
||||||
|
puts "Deleting Administration for #{email}"
|
||||||
|
a = Administration.find_by(email: email)
|
||||||
|
a.destroy
|
||||||
|
puts "#{a.email} deleted"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Admin::MailTemplatesController, type: :controller do
|
describe Admin::MailTemplatesController, type: :controller do
|
||||||
let(:initiated_mail) { Mails::InitiatedMail.default }
|
|
||||||
let(:procedure) { create :procedure }
|
let(:procedure) { create :procedure }
|
||||||
|
let(:initiated_mail) { Mails::InitiatedMail.default_for_procedure(procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in procedure.administrateur
|
sign_in procedure.administrateur
|
||||||
|
|
|
@ -65,7 +65,7 @@ describe API::V1::DossiersController do
|
||||||
let!(:dossier2) { create(:dossier, :with_entreprise, procedure: procedure, state: 'en_construction') }
|
let!(:dossier2) { create(:dossier, :with_entreprise, procedure: procedure, state: 'en_construction') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(Dossier).to receive(:per_page).and_return(1)
|
allow(controller).to receive(:per_page).and_return(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'pagination' do
|
describe 'pagination' do
|
||||||
|
|
|
@ -358,11 +358,15 @@ describe Backoffice::DossiersController, type: :controller do
|
||||||
subject { post :process_dossier, params: { process_action: "close", dossier_id: dossier_id, dossier: { motivation: "Yallah" }}}
|
subject { post :process_dossier, params: { process_action: "close", dossier_id: dossier_id, dossier: { motivation: "Yallah" }}}
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
Timecop.freeze(DateTime.now)
|
||||||
|
|
||||||
expect_any_instance_of(AttestationTemplate)
|
expect_any_instance_of(AttestationTemplate)
|
||||||
.to receive(:attestation_for)
|
.to receive(:attestation_for)
|
||||||
.with(have_attributes(motivation: "Yallah"))
|
.with(have_attributes(motivation: "Yallah", processed_at: DateTime.now))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
after { Timecop.return }
|
||||||
|
|
||||||
it { subject }
|
it { subject }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -237,11 +237,15 @@ describe NewGestionnaire::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
Timecop.freeze(DateTime.now)
|
||||||
|
|
||||||
expect_any_instance_of(AttestationTemplate)
|
expect_any_instance_of(AttestationTemplate)
|
||||||
.to receive(:attestation_for)
|
.to receive(:attestation_for)
|
||||||
.with(have_attributes(motivation: "Yallah"))
|
.with(have_attributes(motivation: "Yallah", processed_at: DateTime.now))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
after { Timecop.return }
|
||||||
|
|
||||||
it { subject }
|
it { subject }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,13 +7,12 @@ describe ProceduresDecorator do
|
||||||
create(:procedure, :published, created_at: Time.new(2015, 12, 24, 14, 10))
|
create(:procedure, :published, created_at: Time.new(2015, 12, 24, 14, 10))
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:procedure) { Procedure.all.paginate(page: 1) }
|
let(:procedure) { Procedure.all.page(1) }
|
||||||
|
|
||||||
subject { procedure.decorate }
|
subject { procedure.decorate }
|
||||||
|
|
||||||
it { expect(subject.current_page).not_to be_nil }
|
it { expect(subject.current_page).not_to be_nil }
|
||||||
it { expect(subject.per_page).not_to be_nil }
|
it { expect(subject.limit_value).not_to be_nil }
|
||||||
it { expect(subject.offset).not_to be_nil }
|
it { expect(subject.count).to eq(3) }
|
||||||
it { expect(subject.total_entries).not_to be_nil }
|
|
||||||
it { expect(subject.total_pages).not_to be_nil }
|
it { expect(subject.total_pages).not_to be_nil }
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
FactoryGirl.define do
|
FactoryGirl.define do
|
||||||
factory :mail_template do
|
factory :mail_template, class: Mails::ClosedMail do
|
||||||
object "Object, voila voila"
|
object "Object, voila voila"
|
||||||
body "Blabla ceci est mon body"
|
body "Blabla ceci est mon body"
|
||||||
type 'MailValidated'
|
|
||||||
|
|
||||||
trait :dossier_submitted do
|
factory :dossier_submitted_mail_template, class: Mails::ReceivedMail
|
||||||
type 'MailSubmitted'
|
|
||||||
end
|
|
||||||
|
|
||||||
trait :dossier_refused do
|
factory :dossier_refused_mail_template, class: Mails::RefusedMail
|
||||||
type 'MailRefused'
|
|
||||||
end
|
|
||||||
|
|
||||||
trait :dossier_en_instruction do
|
factory :dossier_en_instruction_mail_template, class: Mails::InitiatedMail do
|
||||||
object "[TPS] Accusé de réception pour votre dossier nº --numero_dossier--"
|
object "[TPS] Accusé de réception pour votre dossier nº --numéro du dossier--"
|
||||||
body "Votre administration vous confirme la bonne réception de votre dossier nº --numero_dossier--"
|
body "Votre administration vous confirme la bonne réception de votre dossier nº --numéro du dossier--"
|
||||||
type 'MailReceived'
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -146,68 +146,16 @@ describe AttestationTemplate, type: :model do
|
||||||
expect(attestation.pdf.filename).to start_with('attestation')
|
expect(attestation.pdf.filename).to start_with('attestation')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the dossier and the procedure has an individual' do
|
|
||||||
let(:for_individual) { true }
|
|
||||||
let(:individual) { Individual.create(nom: 'nom', prenom: 'prenom', gender: 'Mme') }
|
|
||||||
|
|
||||||
context 'and the template title use the individual tags' do
|
|
||||||
let(:template_title) { '--civilité-- --nom-- --prénom--' }
|
|
||||||
|
|
||||||
it { expect(view_args[:title]).to eq('Mme nom prenom') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the dossier and the procedure has an entreprise' do
|
|
||||||
let(:for_individual) { false }
|
|
||||||
|
|
||||||
context 'and the template title use the entreprise tags' do
|
|
||||||
let(:template_title) do
|
|
||||||
'--SIREN-- --numéro de TVA intracommunautaire-- --SIRET du siège social-- --raison sociale-- --adresse--'
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:expected_title) do
|
|
||||||
"#{entreprise.siren} #{entreprise.numero_tva_intracommunautaire} #{entreprise.siret_siege_social} #{entreprise.raison_sociale} --adresse--"
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(view_args[:title]).to eq(expected_title) }
|
|
||||||
|
|
||||||
context 'and the entreprise has a etablissement with an adresse' do
|
|
||||||
let(:etablissement) { create(:etablissement, adresse: 'adresse') }
|
|
||||||
let(:template_title) { '--adresse--' }
|
|
||||||
|
|
||||||
it { expect(view_args[:title]).to eq(etablissement.inline_adresse) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the procedure has a type de champ named libelleA et libelleB' do
|
context 'when the procedure has a type de champ named libelleA et libelleB' do
|
||||||
let(:types_de_champ) do
|
let(:types_de_champ) do
|
||||||
[create(:type_de_champ_public, libelle: 'libelleA'),
|
[create(:type_de_champ_public, libelle: 'libelleA'),
|
||||||
create(:type_de_champ_public, libelle: 'libelleB')]
|
create(:type_de_champ_public, libelle: 'libelleB')]
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'and the template title is nil' do
|
|
||||||
let(:template_title) { nil }
|
|
||||||
|
|
||||||
it { expect(view_args[:title]).to eq('') }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and it is not used in the template title nor body' do
|
|
||||||
it { expect(view_args[:title]).to eq('title') }
|
|
||||||
it { expect(view_args[:body]).to eq('body') }
|
|
||||||
it { expect(view_args[:created_at]).to eq(Time.now) }
|
|
||||||
it { expect(view_args[:logo]).to eq(attestation_template.logo) }
|
|
||||||
it { expect(view_args[:signature]).to eq(attestation_template.signature) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and the are used in the template title and body' do
|
context 'and the are used in the template title and body' do
|
||||||
let(:template_title) { 'title --libelleA--' }
|
let(:template_title) { 'title --libelleA--' }
|
||||||
let(:template_body) { 'body --libelleB--' }
|
let(:template_body) { 'body --libelleB--' }
|
||||||
|
|
||||||
context 'and their value in the dossier are nil' do
|
|
||||||
it { expect(view_args[:title]).to eq('title ') }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and their value in the dossier are not nil' do
|
context 'and their value in the dossier are not nil' do
|
||||||
before do
|
before do
|
||||||
dossier.champs
|
dossier.champs
|
||||||
|
@ -227,92 +175,5 @@ describe AttestationTemplate, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the dossier has a motivation' do
|
|
||||||
let(:dossier) { create(:dossier, motivation: 'motivation') }
|
|
||||||
|
|
||||||
context 'and the title has some dossier tags' do
|
|
||||||
let(:template_title) { 'title --motivation-- --numéro du dossier--' }
|
|
||||||
|
|
||||||
it { expect(view_args[:title]).to eq("title motivation #{dossier.id}") }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the procedure has a type de champ prive named libelleA' do
|
|
||||||
let(:types_de_champ_private) { [create(:type_de_champ_private, libelle: 'libelleA')] }
|
|
||||||
|
|
||||||
context 'and the are used in the template title' do
|
|
||||||
let(:template_title) { 'title --libelleA--' }
|
|
||||||
|
|
||||||
context 'and its value in the dossier are not nil' do
|
|
||||||
before { dossier.champs_private.first.update_attributes(value: 'libelle1') }
|
|
||||||
|
|
||||||
it { expect(view_args[:title]).to eq('title libelle1') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the procedure has 2 types de champ date and datetime' do
|
|
||||||
let(:types_de_champ) do
|
|
||||||
[create(:type_de_champ_public, libelle: 'date', type_champ: 'date'),
|
|
||||||
create(:type_de_champ_public, libelle: 'datetime', type_champ: 'datetime')]
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and the are used in the template title' do
|
|
||||||
let(:template_title) { 'title --date-- --datetime--' }
|
|
||||||
|
|
||||||
context 'and its value in the dossier are not nil' do
|
|
||||||
before do
|
|
||||||
dossier.champs
|
|
||||||
.select { |champ| champ.type_champ == 'date' }
|
|
||||||
.first
|
|
||||||
.update_attributes(value: '2017-04-15')
|
|
||||||
|
|
||||||
dossier.champs
|
|
||||||
.select { |champ| champ.type_champ == 'datetime' }
|
|
||||||
.first
|
|
||||||
.update_attributes(value: '13/09/2017 09:00')
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(view_args[:title]).to eq('title 15/04/2017 13/09/2017 09:00') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "match breaking and non breaking spaces" do
|
|
||||||
before { dossier.champs.first.update_attributes(value: 'valeur') }
|
|
||||||
|
|
||||||
context "when the tag contains a non breaking space" do
|
|
||||||
let(:template_body) { 'body --mon tag--' }
|
|
||||||
|
|
||||||
context 'and the champ contains the non breaking space' do
|
|
||||||
let(:types_de_champ) { [create(:type_de_champ_public, libelle: 'mon tag')] }
|
|
||||||
|
|
||||||
it { expect(view_args[:body]).to eq('body valeur') }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and the champ has an ordinary space' do
|
|
||||||
let(:types_de_champ) { [create(:type_de_champ_public, libelle: 'mon tag')] }
|
|
||||||
|
|
||||||
it { expect(view_args[:body]).to eq('body valeur') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when the tag contains an ordinay space" do
|
|
||||||
let(:template_body) { 'body --mon tag--' }
|
|
||||||
|
|
||||||
context 'and the champ contains a non breaking space' do
|
|
||||||
let(:types_de_champ) { [create(:type_de_champ_public, libelle: 'mon tag')] }
|
|
||||||
|
|
||||||
it { expect(view_args[:body]).to eq('body valeur') }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'and the champ has an ordinary space' do
|
|
||||||
let(:types_de_champ) { [create(:type_de_champ_public, libelle: 'mon tag')] }
|
|
||||||
|
|
||||||
it { expect(view_args[:body]).to eq('body valeur') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe MailTemplateConcern do
|
describe MailTemplateConcern do
|
||||||
let(:dossier) { create :dossier }
|
let(:procedure) { create(:procedure)}
|
||||||
let(:dossier2) { create :dossier }
|
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||||
let(:initiated_mail) { Mails::InitiatedMail.default }
|
let(:dossier2) { create(:dossier, procedure: procedure) }
|
||||||
|
let(:initiated_mail) { Mails::InitiatedMail.default_for_procedure(procedure) }
|
||||||
|
|
||||||
shared_examples "can replace tokens in template" do
|
shared_examples "can replace tokens in template" do
|
||||||
describe 'with no token to replace' do
|
describe 'with no token to replace' do
|
||||||
|
@ -14,14 +15,14 @@ describe MailTemplateConcern do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'with one token to replace' do
|
describe 'with one token to replace' do
|
||||||
let(:template) { '[TPS] Dossier : --numero_dossier--' }
|
let(:template) { '[TPS] Dossier : --numéro du dossier--' }
|
||||||
it do
|
it do
|
||||||
is_expected.to eq("[TPS] Dossier : #{dossier.id}")
|
is_expected.to eq("[TPS] Dossier : #{dossier.id}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'with multiples tokens to replace' do
|
describe 'with multiples tokens to replace' do
|
||||||
let(:template) { '[TPS] --numero_dossier-- --libelle_procedure-- --lien_dossier--' }
|
let(:template) { '[TPS] --numéro du dossier-- --libellé procédure-- --lien dossier--' }
|
||||||
it do
|
it do
|
||||||
expected =
|
expected =
|
||||||
"[TPS] #{dossier.id} #{dossier.procedure.libelle} " +
|
"[TPS] #{dossier.id} #{dossier.procedure.libelle} " +
|
||||||
|
@ -47,10 +48,10 @@ describe MailTemplateConcern do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.replace_tags' do
|
describe '.replace_tags' do
|
||||||
|
before { initiated_mail.body = "n --numéro du dossier--" }
|
||||||
it "avoids side effects" do
|
it "avoids side effects" do
|
||||||
subject = "n --numero_dossier--"
|
expect(initiated_mail.body_for_dossier(dossier)).to eq("n #{dossier.id}")
|
||||||
expect(initiated_mail.replace_tags(subject, dossier)).to eq("n #{dossier.id}")
|
expect(initiated_mail.body_for_dossier(dossier2)).to eq("n #{dossier2.id}")
|
||||||
expect(initiated_mail.replace_tags(subject, dossier2)).to eq("n #{dossier2.id}")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
241
spec/models/concern/tags_substitution_concern_spec.rb
Normal file
241
spec/models/concern/tags_substitution_concern_spec.rb
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
describe TagsSubstitutionConcern, type: :model do
|
||||||
|
let(:types_de_champ) { [] }
|
||||||
|
let(:types_de_champ_private) { [] }
|
||||||
|
let(:for_individual) { false }
|
||||||
|
|
||||||
|
let(:procedure) do
|
||||||
|
create(:procedure,
|
||||||
|
libelle: 'Une magnifique procédure',
|
||||||
|
types_de_champ: types_de_champ,
|
||||||
|
types_de_champ_private: types_de_champ_private,
|
||||||
|
for_individual: for_individual)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:template_concern) do
|
||||||
|
(Class.new do
|
||||||
|
include TagsSubstitutionConcern
|
||||||
|
public :replace_tags
|
||||||
|
|
||||||
|
def initialize(p)
|
||||||
|
@procedure = p
|
||||||
|
end
|
||||||
|
|
||||||
|
def procedure
|
||||||
|
@procedure
|
||||||
|
end
|
||||||
|
end).new(procedure)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'replace_tags' do
|
||||||
|
let(:individual) { nil }
|
||||||
|
let(:etablissement) { nil }
|
||||||
|
let(:entreprise) { create(:entreprise, etablissement: etablissement) }
|
||||||
|
let!(:dossier) { create(:dossier, procedure: procedure, individual: individual, entreprise: entreprise) }
|
||||||
|
|
||||||
|
before { Timecop.freeze(Time.now) }
|
||||||
|
|
||||||
|
subject { template_concern.replace_tags(template, dossier) }
|
||||||
|
|
||||||
|
after { Timecop.return }
|
||||||
|
|
||||||
|
context 'when the dossier and the procedure has an individual' do
|
||||||
|
let(:for_individual) { true }
|
||||||
|
let(:individual) { Individual.create(nom: 'nom', prenom: 'prenom', gender: 'Mme') }
|
||||||
|
|
||||||
|
context 'and the template use the individual tags' do
|
||||||
|
let(:template) { '--civilité-- --nom-- --prénom--' }
|
||||||
|
|
||||||
|
it { is_expected.to eq('Mme nom prenom') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier and the procedure has an entreprise' do
|
||||||
|
let(:for_individual) { false }
|
||||||
|
|
||||||
|
context 'and the template use the entreprise tags' do
|
||||||
|
let(:template) do
|
||||||
|
'--SIREN-- --numéro de TVA intracommunautaire-- --SIRET du siège social-- --raison sociale-- --adresse--'
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:expected_text) do
|
||||||
|
"#{entreprise.siren} #{entreprise.numero_tva_intracommunautaire} #{entreprise.siret_siege_social} #{entreprise.raison_sociale} --adresse--"
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to eq(expected_text) }
|
||||||
|
|
||||||
|
context 'and the entreprise has a etablissement with an adresse' do
|
||||||
|
let(:etablissement) { create(:etablissement, adresse: 'adresse') }
|
||||||
|
let(:template) { '--adresse--' }
|
||||||
|
|
||||||
|
it { is_expected.to eq(etablissement.inline_adresse) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the procedure has a type de champ named libelleA et libelleB' do
|
||||||
|
let(:types_de_champ) do
|
||||||
|
[create(:type_de_champ_public, libelle: 'libelleA'),
|
||||||
|
create(:type_de_champ_public, libelle: 'libelleB')]
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the template is nil' do
|
||||||
|
let(:template) { nil }
|
||||||
|
|
||||||
|
it { is_expected.to eq('') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and it is not used in the template' do
|
||||||
|
let(:template) { '' }
|
||||||
|
it { is_expected.to eq('') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and they are used in the template' do
|
||||||
|
let(:template) { '--libelleA-- --libelleB--' }
|
||||||
|
|
||||||
|
context 'and their value in the dossier are nil' do
|
||||||
|
it { is_expected.to eq(' ') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and their value in the dossier are not nil' do
|
||||||
|
before do
|
||||||
|
dossier.champs
|
||||||
|
.select { |champ| champ.libelle == 'libelleA' }
|
||||||
|
.first
|
||||||
|
.update_attributes(value: 'libelle1')
|
||||||
|
|
||||||
|
dossier.champs
|
||||||
|
.select { |champ| champ.libelle == 'libelleB' }
|
||||||
|
.first
|
||||||
|
.update_attributes(value: 'libelle2')
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to eq('libelle1 libelle2') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier has a motivation' do
|
||||||
|
let(:dossier) { create(:dossier, motivation: 'motivation') }
|
||||||
|
|
||||||
|
before { dossier.accepte! }
|
||||||
|
|
||||||
|
context 'and the template has some dossier tags' do
|
||||||
|
let(:template) { '--motivation-- --numéro du dossier--' }
|
||||||
|
|
||||||
|
it { is_expected.to eq("motivation #{dossier.id}") }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the procedure has a type de champ prive named libelleA' do
|
||||||
|
let(:types_de_champ_private) { [create(:type_de_champ_private, libelle: 'libelleA')] }
|
||||||
|
|
||||||
|
context 'and the are used in the template' do
|
||||||
|
let(:template) { '--libelleA--' }
|
||||||
|
|
||||||
|
context 'and its value in the dossier are not nil' do
|
||||||
|
before { dossier.champs_private.first.update_attributes(value: 'libelle1') }
|
||||||
|
|
||||||
|
it { is_expected.to eq('libelle1') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the procedure has 2 types de champ date and datetime' do
|
||||||
|
let(:types_de_champ) do
|
||||||
|
[create(:type_de_champ_public, libelle: 'date', type_champ: 'date'),
|
||||||
|
create(:type_de_champ_public, libelle: 'datetime', type_champ: 'datetime')]
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the are used in the template' do
|
||||||
|
let(:template) { '--date-- --datetime--' }
|
||||||
|
|
||||||
|
context 'and its value in the dossier are not nil' do
|
||||||
|
before do
|
||||||
|
dossier.champs
|
||||||
|
.select { |champ| champ.type_champ == 'date' }
|
||||||
|
.first
|
||||||
|
.update_attributes(value: '2017-04-15')
|
||||||
|
|
||||||
|
dossier.champs
|
||||||
|
.select { |champ| champ.type_champ == 'datetime' }
|
||||||
|
.first
|
||||||
|
.update_attributes(value: '13/09/2017 09:00')
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to eq('15/04/2017 13/09/2017 09:00') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the template has a date de décision tag" do
|
||||||
|
let(:template) { '--date de décision--' }
|
||||||
|
|
||||||
|
before { dossier.accepte! }
|
||||||
|
|
||||||
|
it { is_expected.to eq(DateTime.now.localtime.strftime('%d/%m/%Y')) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the template has a libellé procédure tag" do
|
||||||
|
let(:template) { 'body --libellé procédure--' }
|
||||||
|
|
||||||
|
it { is_expected.to eq('body Une magnifique procédure') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "match breaking and non breaking spaces" do
|
||||||
|
before { dossier.champs.first.update_attributes(value: 'valeur') }
|
||||||
|
|
||||||
|
shared_examples "treat all kinds of space as equivalent" do
|
||||||
|
context 'and the champ has a non breaking space' do
|
||||||
|
let(:types_de_champ) { [create(:type_de_champ_public, libelle: 'mon tag')] }
|
||||||
|
|
||||||
|
it { is_expected.to eq('valeur') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the champ has an ordinary space' do
|
||||||
|
let(:types_de_champ) { [create(:type_de_champ_public, libelle: 'mon tag')] }
|
||||||
|
|
||||||
|
it { is_expected.to eq('valeur') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the tag has a non breaking space" do
|
||||||
|
let(:template) { '--mon tag--' }
|
||||||
|
|
||||||
|
it_behaves_like "treat all kinds of space as equivalent"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the tag has an ordinary space" do
|
||||||
|
let(:template) { '--mon tag--' }
|
||||||
|
|
||||||
|
it_behaves_like "treat all kinds of space as equivalent"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when generating a document for a dossier that is not termine' do
|
||||||
|
let(:dossier) { create(:dossier) }
|
||||||
|
let(:template) { '--motivation-- --date de décision--' }
|
||||||
|
|
||||||
|
subject { template_concern.replace_tags(template, dossier) }
|
||||||
|
|
||||||
|
it "does not treat motivation or date de décision as tags" do
|
||||||
|
is_expected.to eq('--motivation-- --date de décision--')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'tags' do
|
||||||
|
context 'when generating a document for a dossier terminé' do
|
||||||
|
subject { template_concern.tags }
|
||||||
|
|
||||||
|
it { is_expected.to include(include({ libelle: 'motivation' })) }
|
||||||
|
it { is_expected.to include(include({ libelle: 'date de décision' })) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when generating a document for a dossier that is not terminé' do
|
||||||
|
subject { template_concern.tags(is_dossier_termine: false) }
|
||||||
|
|
||||||
|
it { is_expected.not_to include(include({ libelle: 'motivation' })) }
|
||||||
|
it { is_expected.not_to include(include({ libelle: 'date de décision' })) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -12,10 +12,12 @@ describe Procedure do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'initiated_mail' do
|
describe 'initiated_mail' do
|
||||||
subject { create(:procedure) }
|
let(:procedure) { create(:procedure) }
|
||||||
|
|
||||||
|
subject { procedure }
|
||||||
|
|
||||||
context 'when initiated_mail is not customize' do
|
context 'when initiated_mail is not customize' do
|
||||||
it { expect(subject.initiated_mail_template.body).to eq(Mails::InitiatedMail.default.body) }
|
it { expect(subject.initiated_mail_template.body).to eq(Mails::InitiatedMail.default_for_procedure(procedure).body) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when initiated_mail is customize' do
|
context 'when initiated_mail is customize' do
|
||||||
|
@ -209,7 +211,7 @@ describe Procedure do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not duplicate default mail_template' do
|
it 'should not duplicate default mail_template' do
|
||||||
expect(subject.initiated_mail_template.attributes).to eq Mails::InitiatedMail.default.attributes
|
expect(subject.initiated_mail_template.attributes).to eq Mails::InitiatedMail.default_for_procedure(subject).attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not duplicate specific related objects' do
|
it 'should not duplicate specific related objects' do
|
||||||
|
|
26
spec/views/admin/mail_templates/edit.html.haml_spec.rb
Normal file
26
spec/views/admin/mail_templates/edit.html.haml_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'admin/mail_templates/edit.html.haml', type: :view do
|
||||||
|
let(:procedure) { create(:procedure) }
|
||||||
|
let(:mail_template) { create(:mail_template, procedure: procedure) }
|
||||||
|
let(:all_tags) { mail_template.tags(reject_legacy: false) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(view).to receive(:admin_procedure_mail_template_path).and_return("/toto")
|
||||||
|
allow(view).to receive(:admin_procedure_mail_templates_path).and_return("/toto")
|
||||||
|
|
||||||
|
assign(:mail_template, mail_template)
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { render }
|
||||||
|
|
||||||
|
context "Legacy champs are not listed in the page" do
|
||||||
|
it { expect(all_tags).to include(include({ libelle: 'numero_dossier', is_legacy: true })) }
|
||||||
|
it { is_expected.not_to include("numero_dossier") }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Non-legacy champs are listed in the page" do
|
||||||
|
it { expect(all_tags).to include(include({ libelle: 'numéro du dossier' })) }
|
||||||
|
it { is_expected.to include("numéro du dossier") }
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue