commit
432f713e6c
19 changed files with 455 additions and 103 deletions
|
@ -144,7 +144,7 @@ Pour les lister : `bin/rake -D support:`.
|
||||||
|
|
||||||
## Compatibilité navigateurs
|
## Compatibilité navigateurs
|
||||||
|
|
||||||
L'application supporte les navigateurs récents : Firefox, Chrome, Safari, Edge et Internet Explorer 11 (voir `config/browser.rb`).
|
L'application supporte les navigateurs récents : Firefox, Chrome, Safari, Edge et Internet Explorer 11 (voir `config/initializers/browser.rb`).
|
||||||
|
|
||||||
La compatibilité est testée par Browserstack.<br>[<img src="app/assets/images/browserstack-logo-600x315.png" width="200">](https://www.browserstack.com/)
|
La compatibilité est testée par Browserstack.<br>[<img src="app/assets/images/browserstack-logo-600x315.png" width="200">](https://www.browserstack.com/)
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,8 @@ class Admin::AttestationTemplatesController < AdminController
|
||||||
# In a case of a preview, when the user does not change its images,
|
# In a case of a preview, when the user does not change its images,
|
||||||
# the images are not uploaded and thus should be retrieved from previous
|
# the images are not uploaded and thus should be retrieved from previous
|
||||||
# attestation_template
|
# attestation_template
|
||||||
@logo = activated_attestation_params[:logo] || @procedure.attestation_template&.logo
|
@logo = activated_attestation_params[:logo_active_storage] || @procedure.attestation_template&.proxy_logo
|
||||||
@signature = activated_attestation_params[:signature] || @procedure.attestation_template&.signature
|
@signature = activated_attestation_params[:signature_active_storage] || @procedure.attestation_template&.proxy_signature
|
||||||
|
|
||||||
render 'admin/attestation_templates/show', formats: [:pdf]
|
render 'admin/attestation_templates/show', formats: [:pdf]
|
||||||
end
|
end
|
||||||
|
@ -57,8 +57,11 @@ class Admin::AttestationTemplatesController < AdminController
|
||||||
def delete_logo
|
def delete_logo
|
||||||
attestation_template = @procedure.attestation_template
|
attestation_template = @procedure.attestation_template
|
||||||
|
|
||||||
|
if attestation_template.logo.present?
|
||||||
attestation_template.remove_logo!
|
attestation_template.remove_logo!
|
||||||
attestation_template.save
|
attestation_template.save
|
||||||
|
end
|
||||||
|
attestation_template.logo_active_storage.purge_later
|
||||||
|
|
||||||
flash.notice = 'le logo a bien été supprimée'
|
flash.notice = 'le logo a bien été supprimée'
|
||||||
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
|
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
|
||||||
|
@ -67,8 +70,11 @@ class Admin::AttestationTemplatesController < AdminController
|
||||||
def delete_signature
|
def delete_signature
|
||||||
attestation_template = @procedure.attestation_template
|
attestation_template = @procedure.attestation_template
|
||||||
|
|
||||||
|
if attestation_template.signature.present?
|
||||||
attestation_template.remove_signature!
|
attestation_template.remove_signature!
|
||||||
attestation_template.save
|
attestation_template.save
|
||||||
|
end
|
||||||
|
attestation_template.signature_active_storage.purge_later
|
||||||
|
|
||||||
flash.notice = 'la signature a bien été supprimée'
|
flash.notice = 'la signature a bien été supprimée'
|
||||||
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
|
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
|
||||||
|
@ -80,11 +86,18 @@ class Admin::AttestationTemplatesController < AdminController
|
||||||
# cache result to avoid multiple uninterlaced computations
|
# cache result to avoid multiple uninterlaced computations
|
||||||
if @activated_attestation_params.nil?
|
if @activated_attestation_params.nil?
|
||||||
@activated_attestation_params = params.require(:attestation_template)
|
@activated_attestation_params = params.require(:attestation_template)
|
||||||
.permit(:title, :body, :footer, :signature)
|
.permit(:title, :body, :footer)
|
||||||
.merge(activated: true)
|
.merge(activated: true)
|
||||||
|
|
||||||
@activated_attestation_params[:logo] = uninterlaced_png(params['attestation_template']['logo'])
|
logo_file = params['attestation_template'].delete('logo')
|
||||||
@activated_attestation_params[:signature] = uninterlaced_png(params['attestation_template']['signature'])
|
signature_file = params['attestation_template'].delete('signature')
|
||||||
|
|
||||||
|
if logo_file.present?
|
||||||
|
@activated_attestation_params[:logo_active_storage] = uninterlaced_png(logo_file)
|
||||||
|
end
|
||||||
|
if signature_file.present?
|
||||||
|
@activated_attestation_params[:signature_active_storage] = uninterlaced_png(signature_file)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@activated_attestation_params
|
@activated_attestation_params
|
||||||
|
|
|
@ -286,7 +286,9 @@ class Admin::ProceduresController < AdminController
|
||||||
else
|
else
|
||||||
params.require(:procedure).permit(*editable_params, :duree_conservation_dossiers_dans_ds, :duree_conservation_dossiers_hors_ds, :for_individual, :path)
|
params.require(:procedure).permit(*editable_params, :duree_conservation_dossiers_dans_ds, :duree_conservation_dossiers_hors_ds, :for_individual, :path)
|
||||||
end
|
end
|
||||||
|
if permited_params[:logo]
|
||||||
permited_params[:logo_active_storage] = permited_params.delete(:logo)
|
permited_params[:logo_active_storage] = permited_params.delete(:logo)
|
||||||
|
end
|
||||||
permited_params
|
permited_params
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,11 +14,22 @@ module Instructeurs
|
||||||
after_action :mark_annotations_privees_as_read, only: [:annotations_privees, :update_annotations]
|
after_action :mark_annotations_privees_as_read, only: [:annotations_privees, :update_annotations]
|
||||||
|
|
||||||
def attestation
|
def attestation
|
||||||
|
if dossier.attestation.pdf_active_storage.attached?
|
||||||
|
redirect_to url_for(dossier.attestation.pdf_active_storage)
|
||||||
|
else
|
||||||
send_data(dossier.attestation.pdf.read, filename: 'attestation.pdf', type: 'application/pdf')
|
send_data(dossier.attestation.pdf.read, filename: 'attestation.pdf', type: 'application/pdf')
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def apercu_attestation
|
def apercu_attestation
|
||||||
send_data(dossier.build_attestation.pdf.read, filename: 'apercu_attestation.pdf', disposition: 'inline', type: 'application/pdf')
|
@title = dossier.procedure.attestation_template.title
|
||||||
|
@body = dossier.procedure.attestation_template.body
|
||||||
|
@footer = dossier.procedure.attestation_template.footer
|
||||||
|
@created_at = Time.zone.now
|
||||||
|
@logo = dossier.procedure.attestation_template&.proxy_logo
|
||||||
|
@signature = dossier.procedure.attestation_template&.proxy_signature
|
||||||
|
|
||||||
|
render 'admin/attestation_templates/show', formats: [:pdf]
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
|
@ -48,8 +48,12 @@ module Users
|
||||||
end
|
end
|
||||||
|
|
||||||
def attestation
|
def attestation
|
||||||
|
if dossier.attestation.pdf_active_storage.attached?
|
||||||
|
redirect_to url_for(dossier.attestation.pdf_active_storage)
|
||||||
|
else
|
||||||
send_data(dossier.attestation.pdf.read, filename: 'attestation.pdf', type: 'application/pdf')
|
send_data(dossier.attestation.pdf.read, filename: 'attestation.pdf', type: 'application/pdf')
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def identite
|
def identite
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
|
|
|
@ -10,7 +10,7 @@ class ApplicationMailer < ActionMailer::Base
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if procedure.logo_active_storage.attached?
|
if procedure.logo_active_storage.attached?
|
||||||
logo_filename = procedure.logo_active_storage.filename
|
logo_filename = procedure.logo_active_storage.filename.to_s
|
||||||
attachments.inline[logo_filename] = procedure.logo_active_storage.download
|
attachments.inline[logo_filename] = procedure.logo_active_storage.download
|
||||||
else
|
else
|
||||||
logo_filename = procedure.logo.filename
|
logo_filename = procedure.logo.filename
|
||||||
|
|
|
@ -3,8 +3,12 @@ class Attestation < ApplicationRecord
|
||||||
|
|
||||||
mount_uploader :pdf, AttestationUploader
|
mount_uploader :pdf, AttestationUploader
|
||||||
|
|
||||||
|
has_one_attached :pdf_active_storage
|
||||||
|
|
||||||
def pdf_url
|
def pdf_url
|
||||||
if Rails.application.secrets.fog[:enabled]
|
if pdf_active_storage.attached?
|
||||||
|
Rails.application.routes.url_helpers.url_for(pdf_active_storage)
|
||||||
|
elsif Rails.application.secrets.fog[:enabled]
|
||||||
RemoteDownloader.new(pdf.path).url
|
RemoteDownloader.new(pdf.path).url
|
||||||
elsif pdf&.url
|
elsif pdf&.url
|
||||||
# FIXME: this is horrible but used only in dev and will be removed after migration
|
# FIXME: this is horrible but used only in dev and will be removed after migration
|
||||||
|
|
|
@ -7,14 +7,23 @@ class AttestationTemplate < ApplicationRecord
|
||||||
mount_uploader :logo, AttestationTemplateLogoUploader
|
mount_uploader :logo, AttestationTemplateLogoUploader
|
||||||
mount_uploader :signature, AttestationTemplateSignatureUploader
|
mount_uploader :signature, AttestationTemplateSignatureUploader
|
||||||
|
|
||||||
validate :logo_signature_file_size
|
has_one_attached :logo_active_storage
|
||||||
|
has_one_attached :signature_active_storage
|
||||||
|
|
||||||
validates :footer, length: { maximum: 190 }
|
validates :footer, length: { maximum: 190 }
|
||||||
|
|
||||||
FILE_MAX_SIZE_IN_MB = 0.5
|
|
||||||
DOSSIER_STATE = Dossier.states.fetch(:accepte)
|
DOSSIER_STATE = Dossier.states.fetch(:accepte)
|
||||||
|
|
||||||
def attestation_for(dossier)
|
def attestation_for(dossier)
|
||||||
Attestation.new(title: replace_tags(title, dossier), pdf: build_pdf(dossier))
|
attestation = Attestation.new(title: replace_tags(title, dossier))
|
||||||
|
attestation.pdf_active_storage.attach(
|
||||||
|
io: build_pdf(dossier),
|
||||||
|
filename: "attestation-dossier-#{dossier.id}.pdf",
|
||||||
|
content_type: 'application/pdf',
|
||||||
|
# we don't want to run virus scanner on this file
|
||||||
|
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||||
|
)
|
||||||
|
attestation
|
||||||
end
|
end
|
||||||
|
|
||||||
def unspecified_champs_for_dossier(dossier)
|
def unspecified_champs_for_dossier(dossier)
|
||||||
|
@ -34,17 +43,83 @@ class AttestationTemplate < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def dup
|
def dup
|
||||||
result = AttestationTemplate.new(title: title, body: body, footer: footer, activated: activated)
|
attestation_template = AttestationTemplate.new(title: title, body: body, footer: footer, activated: activated)
|
||||||
|
|
||||||
if logo.present?
|
if logo_active_storage.attached?
|
||||||
CopyCarrierwaveFile::CopyFileService.new(self, result, :logo).set_file
|
attestation_template.logo_active_storage.attach(
|
||||||
|
io: StringIO.new(logo_active_storage.download),
|
||||||
|
filename: logo_active_storage.filename,
|
||||||
|
content_type: logo_active_storage.content_type,
|
||||||
|
# we don't want to run virus scanner on duplicated file
|
||||||
|
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||||
|
)
|
||||||
|
elsif logo.present?
|
||||||
|
CopyCarrierwaveFile::CopyFileService.new(self, attestation_template, :logo).set_file
|
||||||
end
|
end
|
||||||
|
|
||||||
if signature.present?
|
if signature_active_storage.attached?
|
||||||
CopyCarrierwaveFile::CopyFileService.new(self, result, :signature).set_file
|
attestation_template.signature_active_storage.attach(
|
||||||
|
io: StringIO.new(signature_active_storage.download),
|
||||||
|
filename: signature_active_storage.filename,
|
||||||
|
content_type: signature_active_storage.content_type,
|
||||||
|
# we don't want to run virus scanner on duplicated file
|
||||||
|
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||||
|
)
|
||||||
|
elsif signature.present?
|
||||||
|
CopyCarrierwaveFile::CopyFileService.new(self, attestation_template, :signature).set_file
|
||||||
end
|
end
|
||||||
|
|
||||||
result
|
attestation_template
|
||||||
|
end
|
||||||
|
|
||||||
|
def logo?
|
||||||
|
logo_active_storage.attached? || logo.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def signature?
|
||||||
|
signature_active_storage.attached? || signature.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def logo_url
|
||||||
|
if logo_active_storage.attached?
|
||||||
|
Rails.application.routes.url_helpers.url_for(logo_active_storage)
|
||||||
|
elsif logo.present?
|
||||||
|
if Rails.application.secrets.fog[:enabled]
|
||||||
|
RemoteDownloader.new(logo.path).url
|
||||||
|
elsif logo&.url
|
||||||
|
# FIXME: this is horrible but used only in dev and will be removed after migration
|
||||||
|
File.join(LOCAL_DOWNLOAD_URL, logo.url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def signature_url
|
||||||
|
if signature_active_storage.attached?
|
||||||
|
Rails.application.routes.url_helpers.url_for(signature_active_storage)
|
||||||
|
elsif signature.present?
|
||||||
|
if Rails.application.secrets.fog[:enabled]
|
||||||
|
RemoteDownloader.new(signature.path).url
|
||||||
|
elsif signature&.url
|
||||||
|
# FIXME: this is horrible but used only in dev and will be removed after migration
|
||||||
|
File.join(LOCAL_DOWNLOAD_URL, signature.url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy_logo
|
||||||
|
if logo_active_storage.attached?
|
||||||
|
logo_active_storage
|
||||||
|
else
|
||||||
|
logo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy_signature
|
||||||
|
if signature_active_storage.attached?
|
||||||
|
signature_active_storage
|
||||||
|
else
|
||||||
|
signature
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -60,40 +135,17 @@ class AttestationTemplate < ApplicationRecord
|
||||||
.flatten
|
.flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
def logo_signature_file_size
|
|
||||||
[:logo, :signature]
|
|
||||||
.select { |file_name| send(file_name).present? }
|
|
||||||
.each { |file_name| file_size_check(file_name) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def file_size_check(file_name)
|
|
||||||
if send(file_name).file.size.to_f > FILE_MAX_SIZE_IN_MB.megabyte.to_f
|
|
||||||
errors.add(file_name, " : vous ne pouvez pas charger une image de plus de #{number_with_delimiter(FILE_MAX_SIZE_IN_MB, locale: :fr)} Mo")
|
|
||||||
end
|
|
||||||
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: proxy_logo,
|
||||||
title: replace_tags(title, dossier),
|
title: replace_tags(title, dossier),
|
||||||
body: replace_tags(body, dossier),
|
body: replace_tags(body, dossier),
|
||||||
signature: signature,
|
signature: proxy_signature,
|
||||||
footer: footer,
|
footer: footer,
|
||||||
created_at: Time.zone.now)
|
created_at: Time.zone.now)
|
||||||
|
|
||||||
attestation_view = action_view.render(file: 'admin/attestation_templates/show',
|
attestation_view = action_view.render(file: 'admin/attestation_templates/show', formats: [:pdf])
|
||||||
formats: [:pdf])
|
|
||||||
|
|
||||||
view_to_memory_file(attestation_view)
|
StringIO.new(attestation_view)
|
||||||
end
|
|
||||||
|
|
||||||
def view_to_memory_file(view)
|
|
||||||
pdf = StringIO.new(view)
|
|
||||||
|
|
||||||
def pdf.original_filename
|
|
||||||
'attestation'
|
|
||||||
end
|
|
||||||
|
|
||||||
pdf
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -70,6 +70,10 @@ class ProcedureExportV2Service
|
||||||
row_style: { background_color: nil, color: "000000", font_size: 12 }
|
row_style: { background_color: nil, color: "000000", font_size: 12 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def sanitize_sheet_name(name)
|
||||||
|
ActiveStorage::Filename.new(name.to_s).sanitized.truncate(30)
|
||||||
|
end
|
||||||
|
|
||||||
def options_for(table)
|
def options_for(table)
|
||||||
case table
|
case table
|
||||||
when :dossiers
|
when :dossiers
|
||||||
|
@ -80,7 +84,7 @@ class ProcedureExportV2Service
|
||||||
{ instances: avis.to_a, sheet_name: 'Avis' }.merge(DEFAULT_STYLES)
|
{ instances: avis.to_a, sheet_name: 'Avis' }.merge(DEFAULT_STYLES)
|
||||||
when Array
|
when Array
|
||||||
# We have to truncate the label here as spreadsheets have a (30 char) limit on length.
|
# We have to truncate the label here as spreadsheets have a (30 char) limit on length.
|
||||||
{ instances: table.last, sheet_name: table.first.to_s.truncate(30) }.merge(DEFAULT_STYLES)
|
{ instances: table.last, sheet_name: sanitize_sheet_name(table.first) }.merge(DEFAULT_STYLES)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,8 +19,10 @@ class AttestationUploader < BaseUploader
|
||||||
end
|
end
|
||||||
|
|
||||||
def filename
|
def filename
|
||||||
|
if file.present?
|
||||||
"attestation-#{secure_token}.pdf"
|
"attestation-#{secure_token}.pdf"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
celle-ci est également disponible au téléchargement depuis l’espace personnel de l’usager.
|
celle-ci est également disponible au téléchargement depuis l’espace personnel de l’usager.
|
||||||
|
|
||||||
.image-upload
|
.image-upload
|
||||||
- if @attestation_template.logo.present?
|
- if @attestation_template.logo?
|
||||||
= image_tag @attestation_template.logo.url, class: 'thumbnail'
|
= image_tag @attestation_template.logo_url, class: 'thumbnail'
|
||||||
.form-group
|
.form-group
|
||||||
= f.label :logo, "Logo de l'attestation"
|
= f.label :logo, "Logo de l'attestation"
|
||||||
- if @attestation_template.logo.present?
|
- if @attestation_template.logo?
|
||||||
= link_to 'Supprimer le logo', admin_procedure_attestation_template_logo_path(@procedure), method: :delete
|
= link_to 'Supprimer le logo', admin_procedure_attestation_template_logo_path(@procedure), method: :delete
|
||||||
= f.file_field :logo, accept: 'image/png, image/jpg, image/jpeg'
|
= f.file_field :logo, accept: 'image/png, image/jpg, image/jpeg'
|
||||||
%p.help-block
|
%p.help-block
|
||||||
|
@ -54,11 +54,11 @@
|
||||||
= tag[:description]
|
= tag[:description]
|
||||||
|
|
||||||
.image-upload
|
.image-upload
|
||||||
- if @attestation_template.signature.present?
|
- if @attestation_template.signature?
|
||||||
= image_tag @attestation_template.signature.url, class: 'thumbnail'
|
= image_tag @attestation_template.signature_url, class: 'thumbnail'
|
||||||
.form-group
|
.form-group
|
||||||
= f.label :signature, "Tampon de l'attestation"
|
= f.label :signature, "Tampon de l'attestation"
|
||||||
- if @attestation_template.signature.present?
|
- if @attestation_template.signature?
|
||||||
= link_to 'Supprimer le tampon', admin_procedure_attestation_template_signature_path(@procedure), method: :delete
|
= link_to 'Supprimer le tampon', admin_procedure_attestation_template_signature_path(@procedure), method: :delete
|
||||||
= f.file_field :signature, accept: 'image/png, image/jpg, image/jpeg'
|
= f.file_field :signature, accept: 'image/png, image/jpg, image/jpeg'
|
||||||
%p.help-block
|
%p.help-block
|
||||||
|
|
|
@ -30,7 +30,12 @@ prawn_document(margin: [top_margin, right_margin, bottom_margin, left_margin], p
|
||||||
|
|
||||||
pdf.bounding_box([0, pdf.cursor], width: body_width, height: body_height) do
|
pdf.bounding_box([0, pdf.cursor], width: body_width, height: body_height) do
|
||||||
if @logo.present?
|
if @logo.present?
|
||||||
pdf.image StringIO.new(@logo.read), fit: [max_logo_width , max_logo_height], position: :center
|
logo_file = if @logo.is_a?(ActiveStorage::Attached::One)
|
||||||
|
@logo.download
|
||||||
|
else
|
||||||
|
@logo.read
|
||||||
|
end
|
||||||
|
pdf.image StringIO.new(logo_file), fit: [max_logo_width , max_logo_height], position: :center
|
||||||
end
|
end
|
||||||
|
|
||||||
pdf.fill_color grey
|
pdf.fill_color grey
|
||||||
|
@ -44,7 +49,12 @@ prawn_document(margin: [top_margin, right_margin, bottom_margin, left_margin], p
|
||||||
|
|
||||||
if @signature.present?
|
if @signature.present?
|
||||||
pdf.pad_top(40) do
|
pdf.pad_top(40) do
|
||||||
pdf.image StringIO.new(@signature.read), fit: [max_signature_size , max_signature_size], position: :right
|
signature_file = if @signature.is_a?(ActiveStorage::Attached::One)
|
||||||
|
@signature.download
|
||||||
|
else
|
||||||
|
@signature.read
|
||||||
|
end
|
||||||
|
pdf.image StringIO.new(signature_file), fit: [max_signature_size , max_signature_size], position: :right
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
97
lib/tasks/2019_08_22_migrate_attestation_files.rake
Normal file
97
lib/tasks/2019_08_22_migrate_attestation_files.rake
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
namespace :'2019_08_22_migrate_attestation_files' do
|
||||||
|
task migrate_attestation_pdf: :environment do
|
||||||
|
attestations = Attestation.where
|
||||||
|
.not(pdf: nil)
|
||||||
|
.left_joins(:pdf_active_storage_attachment)
|
||||||
|
.where('active_storage_attachments.id IS NULL')
|
||||||
|
.order(:created_at)
|
||||||
|
|
||||||
|
limit = ENV['LIMIT']
|
||||||
|
if limit
|
||||||
|
attestations.limit!(limit.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
progress = ProgressReport.new(attestations.count)
|
||||||
|
attestations.find_each do |attestation|
|
||||||
|
if attestation.pdf.present?
|
||||||
|
uri = URI.parse(URI.escape(attestation.pdf_url))
|
||||||
|
response = Typhoeus.get(uri)
|
||||||
|
if response.success?
|
||||||
|
filename = attestation.pdf.filename || attestation.pdf_identifier
|
||||||
|
attestation.pdf_active_storage.attach(
|
||||||
|
io: StringIO.new(response.body),
|
||||||
|
filename: filename,
|
||||||
|
content_type: attestation.pdf.content_type,
|
||||||
|
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
progress.inc
|
||||||
|
end
|
||||||
|
progress.finish
|
||||||
|
end
|
||||||
|
|
||||||
|
task migrate_attestation_template_logo: :environment do
|
||||||
|
attestation_templates = AttestationTemplate.where
|
||||||
|
.not(logo: nil)
|
||||||
|
.left_joins(:logo_active_storage_attachment)
|
||||||
|
.where('active_storage_attachments.id IS NULL')
|
||||||
|
.order(:created_at)
|
||||||
|
|
||||||
|
limit = ENV['LIMIT']
|
||||||
|
if limit
|
||||||
|
attestation_templates.limit!(limit.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
progress = ProgressReport.new(attestation_templates.count)
|
||||||
|
attestation_templates.find_each do |attestation_template|
|
||||||
|
if attestation_template.logo.present?
|
||||||
|
uri = URI.parse(URI.escape(attestation_template.logo_url))
|
||||||
|
response = Typhoeus.get(uri)
|
||||||
|
if response.success?
|
||||||
|
filename = attestation_template.logo.filename || attestation_template.logo_identifier
|
||||||
|
attestation_template.logo_active_storage.attach(
|
||||||
|
io: StringIO.new(response.body),
|
||||||
|
filename: filename,
|
||||||
|
content_type: attestation_template.logo.content_type,
|
||||||
|
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
progress.inc
|
||||||
|
end
|
||||||
|
progress.finish
|
||||||
|
end
|
||||||
|
|
||||||
|
task migrate_attestation_template_signature: :environment do
|
||||||
|
attestation_templates = AttestationTemplate.where
|
||||||
|
.not(signature: nil)
|
||||||
|
.left_joins(:signature_active_storage_attachment)
|
||||||
|
.where('active_storage_attachments.id IS NULL')
|
||||||
|
.order(:created_at)
|
||||||
|
|
||||||
|
limit = ENV['LIMIT']
|
||||||
|
if limit
|
||||||
|
attestation_templates.limit!(limit.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
progress = ProgressReport.new(attestation_templates.count)
|
||||||
|
attestation_templates.find_each do |attestation_template|
|
||||||
|
if attestation_template.signature.present?
|
||||||
|
uri = URI.parse(URI.escape(attestation_template.signature_url))
|
||||||
|
response = Typhoeus.get(uri)
|
||||||
|
if response.success?
|
||||||
|
filename = attestation_template.signature.filename || attestation_template.signature_identifier
|
||||||
|
attestation_template.signature_active_storage.attach(
|
||||||
|
io: StringIO.new(response.body),
|
||||||
|
filename: filename,
|
||||||
|
content_type: attestation_template.signature.content_type,
|
||||||
|
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
progress.inc
|
||||||
|
end
|
||||||
|
progress.finish
|
||||||
|
end
|
||||||
|
end
|
|
@ -87,8 +87,8 @@ describe Admin::AttestationTemplatesController, type: :controller do
|
||||||
|
|
||||||
it { expect(procedure.attestation_template).to have_attributes(attestation_params) }
|
it { expect(procedure.attestation_template).to have_attributes(attestation_params) }
|
||||||
it { expect(procedure.attestation_template.activated).to be true }
|
it { expect(procedure.attestation_template.activated).to be true }
|
||||||
it { expect(procedure.attestation_template.logo.read).to eq(logo2.read) }
|
it { expect(procedure.attestation_template.logo_active_storage.download).to eq(logo2.read) }
|
||||||
it { expect(procedure.attestation_template.signature.read).to eq(signature2.read) }
|
it { expect(procedure.attestation_template.signature_active_storage.download).to eq(signature2.read) }
|
||||||
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
||||||
it { expect(flash.notice).to eq("L'attestation a bien été sauvegardée") }
|
it { expect(flash.notice).to eq("L'attestation a bien été sauvegardée") }
|
||||||
|
|
||||||
|
@ -130,8 +130,8 @@ describe Admin::AttestationTemplatesController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(procedure.attestation_template).to have_attributes(attestation_params) }
|
it { expect(procedure.attestation_template).to have_attributes(attestation_params) }
|
||||||
it { expect(procedure.attestation_template.logo.read).to eq(logo2.read) }
|
it { expect(procedure.attestation_template.logo_active_storage.download).to eq(logo2.read) }
|
||||||
it { expect(procedure.attestation_template.signature.read).to eq(signature2.read) }
|
it { expect(procedure.attestation_template.signature_active_storage.download).to eq(signature2.read) }
|
||||||
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
||||||
it { expect(flash.notice).to eq("L'attestation a bien été modifiée") }
|
it { expect(flash.notice).to eq("L'attestation a bien été modifiée") }
|
||||||
|
|
||||||
|
|
10
spec/factories/attestation.rb
Normal file
10
spec/factories/attestation.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :attestation do
|
||||||
|
title { 'title' }
|
||||||
|
dossier { create(:dossier) }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :with_legacy_pdf do
|
||||||
|
pdf { Rack::Test::UploadedFile.new("./spec/fixtures/files/dossierPDF.pdf", 'application/pdf') }
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,4 +5,14 @@ FactoryBot.define do
|
||||||
footer { 'footer' }
|
footer { 'footer' }
|
||||||
activated { true }
|
activated { true }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :with_files do
|
||||||
|
logo_active_storage { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') }
|
||||||
|
signature_active_storage { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :with_legacy_files do
|
||||||
|
logo { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') }
|
||||||
|
signature { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
128
spec/lib/tasks/2019_08_22_migrate_attestation_files_spec.rb
Normal file
128
spec/lib/tasks/2019_08_22_migrate_attestation_files_spec.rb
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
describe '2019_08_22_migrate_attestation_files.rake' do
|
||||||
|
let(:rake_task) { Rake::Task["2019_08_22_migrate_attestation_files:#{sub_task}"] }
|
||||||
|
|
||||||
|
let(:run_task) do
|
||||||
|
rake_task.invoke
|
||||||
|
models.each(&:reload)
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
ENV['LIMIT'] = nil
|
||||||
|
rake_task.reenable
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'attestation' do
|
||||||
|
let(:models) do
|
||||||
|
[
|
||||||
|
create(:attestation, created_at: 3.days.ago),
|
||||||
|
create(:attestation, :with_legacy_pdf, created_at: 2.days.ago),
|
||||||
|
create(:attestation, :with_legacy_pdf, created_at: 1.day.ago)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
first_attestation = models[0]
|
||||||
|
expect(first_attestation.pdf.present?).to be_falsey
|
||||||
|
expect(first_attestation.read_attribute(:pdf)).to be_nil
|
||||||
|
|
||||||
|
models.each do |attestation|
|
||||||
|
if attestation.pdf.present?
|
||||||
|
stub_request(:get, attestation.pdf_url)
|
||||||
|
.to_return(status: 200, body: File.read(attestation.pdf.path))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'pdf' do
|
||||||
|
let(:sub_task) { 'migrate_attestation_pdf' }
|
||||||
|
|
||||||
|
it 'should migrate pdf' do
|
||||||
|
expect(models.map(&:pdf_active_storage).map(&:attached?)).to eq([false, false, false])
|
||||||
|
|
||||||
|
run_task
|
||||||
|
|
||||||
|
expect(Attestation.where(pdf: nil).count).to eq(1)
|
||||||
|
expect(models.map(&:pdf_active_storage).map(&:attached?)).to eq([false, true, true])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should migrate pdf within limit' do
|
||||||
|
expect(models.map(&:pdf_active_storage).map(&:attached?)).to eq([false, false, false])
|
||||||
|
|
||||||
|
ENV['LIMIT'] = '1'
|
||||||
|
run_task
|
||||||
|
|
||||||
|
expect(Attestation.where(pdf: nil).count).to eq(1)
|
||||||
|
expect(models.map(&:pdf_active_storage).map(&:attached?)).to eq([false, true, false])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'attestation_templates' do
|
||||||
|
let(:models) do
|
||||||
|
[
|
||||||
|
create(:attestation_template),
|
||||||
|
create(:attestation_template, :with_legacy_files),
|
||||||
|
create(:attestation_template, :with_legacy_files)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
models.each do |attestation_template|
|
||||||
|
if attestation_template.logo.present?
|
||||||
|
stub_request(:get, attestation_template.logo_url)
|
||||||
|
.to_return(status: 200, body: File.read(attestation_template.logo.path))
|
||||||
|
end
|
||||||
|
if attestation_template.signature.present?
|
||||||
|
stub_request(:get, attestation_template.signature_url)
|
||||||
|
.to_return(status: 200, body: File.read(attestation_template.signature.path))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'logo' do
|
||||||
|
let(:sub_task) { 'migrate_attestation_template_logo' }
|
||||||
|
|
||||||
|
it 'should migrate logo' do
|
||||||
|
expect(models.map(&:logo_active_storage).map(&:attached?)).to eq([false, false, false])
|
||||||
|
|
||||||
|
run_task
|
||||||
|
|
||||||
|
expect(AttestationTemplate.where(logo: nil).count).to eq(1)
|
||||||
|
expect(models.map(&:logo_active_storage).map(&:attached?)).to eq([false, true, true])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should migrate logo within limit' do
|
||||||
|
expect(models.map(&:logo_active_storage).map(&:attached?)).to eq([false, false, false])
|
||||||
|
|
||||||
|
ENV['LIMIT'] = '1'
|
||||||
|
run_task
|
||||||
|
|
||||||
|
expect(AttestationTemplate.where(logo: nil).count).to eq(1)
|
||||||
|
expect(models.map(&:logo_active_storage).map(&:attached?)).to eq([false, true, false])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'signature' do
|
||||||
|
let(:sub_task) { 'migrate_attestation_template_signature' }
|
||||||
|
|
||||||
|
it 'should migrate signature' do
|
||||||
|
expect(models.map(&:signature_active_storage).map(&:attached?)).to eq([false, false, false])
|
||||||
|
|
||||||
|
run_task
|
||||||
|
|
||||||
|
expect(AttestationTemplate.where(signature: nil).count).to eq(1)
|
||||||
|
expect(models.map(&:signature_active_storage).map(&:attached?)).to eq([false, true, true])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should migrate signature within limit' do
|
||||||
|
expect(models.map(&:signature_active_storage).map(&:attached?)).to eq([false, false, false])
|
||||||
|
|
||||||
|
ENV['LIMIT'] = '1'
|
||||||
|
run_task
|
||||||
|
|
||||||
|
expect(AttestationTemplate.where(signature: nil).count).to eq(1)
|
||||||
|
expect(models.map(&:signature_active_storage).map(&:attached?)).to eq([false, true, false])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,44 +1,44 @@
|
||||||
describe AttestationTemplate, type: :model do
|
describe AttestationTemplate, type: :model do
|
||||||
describe 'validate' do
|
# describe 'validate' do
|
||||||
let(:logo_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte }
|
# let(:logo_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte }
|
||||||
let(:signature_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte }
|
# let(:signature_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte }
|
||||||
let(:fake_logo) { double(AttestationTemplateLogoUploader, file: double(size: logo_size)) }
|
# let(:fake_logo) { double(AttestationTemplateLogoUploader, file: double(size: logo_size)) }
|
||||||
let(:fake_signature) { double(AttestationTemplateSignatureUploader, file: double(size: signature_size)) }
|
# let(:fake_signature) { double(AttestationTemplateSignatureUploader, file: double(size: signature_size)) }
|
||||||
let(:attestation_template) { AttestationTemplate.new }
|
# let(:attestation_template) { AttestationTemplate.new }
|
||||||
|
|
||||||
before do
|
# before do
|
||||||
allow(attestation_template).to receive(:logo).and_return(fake_logo)
|
# allow(attestation_template).to receive(:logo).and_return(fake_logo)
|
||||||
allow(attestation_template).to receive(:signature).and_return(fake_signature)
|
# allow(attestation_template).to receive(:signature).and_return(fake_signature)
|
||||||
attestation_template.validate
|
# attestation_template.validate
|
||||||
end
|
# end
|
||||||
|
|
||||||
subject { attestation_template.errors.details }
|
# subject { attestation_template.errors.details }
|
||||||
|
|
||||||
context 'when no files are present' do
|
# context 'when no files are present' do
|
||||||
let(:fake_logo) { nil }
|
# let(:fake_logo) { nil }
|
||||||
let(:fake_signature) { nil }
|
# let(:fake_signature) { nil }
|
||||||
|
|
||||||
it { is_expected.to match({}) }
|
# it { is_expected.to match({}) }
|
||||||
end
|
# end
|
||||||
|
|
||||||
context 'when the logo and the signature have the right size' do
|
# context 'when the logo and the signature have the right size' do
|
||||||
it { is_expected.to match({}) }
|
# it { is_expected.to match({}) }
|
||||||
end
|
# end
|
||||||
|
|
||||||
context 'when the logo and the signature are too heavy' do
|
# context 'when the logo and the signature are too heavy' do
|
||||||
let(:logo_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte + 1 }
|
# let(:logo_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte + 1 }
|
||||||
let(:signature_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte + 1 }
|
# let(:signature_size) { AttestationTemplate::FILE_MAX_SIZE_IN_MB.megabyte + 1 }
|
||||||
|
|
||||||
it do
|
# it do
|
||||||
expected = {
|
# expected = {
|
||||||
signature: [{ error: ' : vous ne pouvez pas charger une image de plus de 0,5 Mo' }],
|
# signature: [{ error: ' : vous ne pouvez pas charger une image de plus de 0,5 Mo' }],
|
||||||
logo: [{ error: ' : vous ne pouvez pas charger une image de plus de 0,5 Mo' }]
|
# logo: [{ error: ' : vous ne pouvez pas charger une image de plus de 0,5 Mo' }]
|
||||||
}
|
# }
|
||||||
|
|
||||||
is_expected.to match(expected)
|
# is_expected.to match(expected)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
describe 'validates footer length' do
|
describe 'validates footer length' do
|
||||||
let(:attestation_template) { AttestationTemplate.new(footer: footer) }
|
let(:attestation_template) { AttestationTemplate.new(footer: footer) }
|
||||||
|
@ -140,11 +140,6 @@ describe AttestationTemplate, type: :model do
|
||||||
|
|
||||||
let(:attestation) { attestation_template.attestation_for(dossier) }
|
let(:attestation) { attestation_template.attestation_for(dossier) }
|
||||||
|
|
||||||
it 'provides a pseudo file' do
|
|
||||||
expect(attestation.pdf.file).to exist
|
|
||||||
expect(attestation.pdf.filename).to start_with('attestation')
|
|
||||||
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
|
||||||
[
|
[
|
||||||
|
|
|
@ -184,6 +184,16 @@ describe ProcedureExportV2Service do
|
||||||
it 'should have data' do
|
it 'should have data' do
|
||||||
expect(repetition_sheet.data.size).to eq(4)
|
expect(repetition_sheet.data.size).to eq(4)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with invalid characters' do
|
||||||
|
before do
|
||||||
|
champ_repetition.type_de_champ.update(libelle: 'A / B \ C')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have valid sheet name' do
|
||||||
|
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', "A - B - C"])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue