diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b146affec..573f581cc 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -21,7 +21,7 @@ class ApplicationController < ActionController::Base before_action :setup_tracking helper_method :multiple_devise_profile_connect?, :instructeur_signed_in?, :current_instructeur, - :administrateur_signed_in?, :current_administrateur + :administrateur_signed_in?, :current_administrateur, :current_account def staging_authenticate if StagingAuthService.enabled? && !authenticate_with_http_basic { |username, password| StagingAuthService.authenticate(username, password) } @@ -49,14 +49,6 @@ class ApplicationController < ActionController::Base user_signed_in? && administrateur_signed_in? end - def pundit_user - { - administrateur: current_administrateur, - instructeur: current_instructeur, - user: current_user - }.compact - end - def current_instructeur current_user&.instructeur end @@ -73,6 +65,16 @@ class ApplicationController < ActionController::Base current_administrateur.present? end + def current_account + { + administrateur: current_administrateur, + instructeur: current_instructeur, + user: current_user + }.compact + end + + alias_method :pundit_user, :current_account + protected def feature_enabled?(feature_name) diff --git a/app/jobs/api_entreprise/effectifs_job.rb b/app/jobs/api_entreprise/effectifs_job.rb index 65aeb278a..321309e0b 100644 --- a/app/jobs/api_entreprise/effectifs_job.rb +++ b/app/jobs/api_entreprise/effectifs_job.rb @@ -1,8 +1,8 @@ class ApiEntreprise::EffectifsJob < ApiEntreprise::Job def perform(etablissement_id, procedure_id) etablissement = Etablissement.find(etablissement_id) - # april 2020 is at the moment the most actual info for effectifs endpoint - etablissement_params = ApiEntreprise::EffectifsAdapter.new(etablissement.siret, procedure_id, "2020", "04").to_params + # may 2020 is at the moment the most actual info for effectifs endpoint + etablissement_params = ApiEntreprise::EffectifsAdapter.new(etablissement.siret, procedure_id, "2020", "05").to_params etablissement.update!(etablissement_params) end diff --git a/app/models/champ.rb b/app/models/champ.rb index af5737e31..8eb94f442 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -11,7 +11,22 @@ class Champ < ApplicationRecord belongs_to :etablissement, dependent: :destroy has_many :champs, -> { ordered }, foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy - delegate :libelle, :type_champ, :procedure, :order_place, :mandatory?, :description, :drop_down_list, :exclude_from_export?, :exclude_from_view?, :repetition?, :dossier_link?, to: :type_de_champ + delegate :libelle, + :type_champ, + :procedure, + :order_place, + :mandatory?, + :description, + :drop_down_list, + :drop_down_list_options, + :drop_down_list_options?, + :drop_down_list_disabled_options, + :drop_down_list_enabled_non_empty_options, + :exclude_from_export?, + :exclude_from_view?, + :repetition?, + :dossier_link?, + to: :type_de_champ scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) } scope :public_only, -> { where(private: false) } diff --git a/app/models/champs/drop_down_list_champ.rb b/app/models/champs/drop_down_list_champ.rb index df3d14dfc..3d007c58a 100644 --- a/app/models/champs/drop_down_list_champ.rb +++ b/app/models/champs/drop_down_list_champ.rb @@ -1,2 +1,23 @@ class Champs::DropDownListChamp < Champ + THRESHOLD_NB_OPTIONS_AS_RADIO = 5 + + def render_as_radios? + enabled_non_empty_options.size <= THRESHOLD_NB_OPTIONS_AS_RADIO + end + + def options? + drop_down_list_options? + end + + def options + drop_down_list_options + end + + def disabled_options + drop_down_list_disabled_options + end + + def enabled_non_empty_options + drop_down_list_enabled_non_empty_options + end end diff --git a/app/models/champs/linked_drop_down_list_champ.rb b/app/models/champs/linked_drop_down_list_champ.rb index 53e02d880..0393bf475 100644 --- a/app/models/champs/linked_drop_down_list_champ.rb +++ b/app/models/champs/linked_drop_down_list_champ.rb @@ -1,6 +1,10 @@ class Champs::LinkedDropDownListChamp < Champ delegate :primary_options, :secondary_options, to: 'type_de_champ.dynamic_type' + def options? + drop_down_list_options? + end + def primary_value if value.present? JSON.parse(value)[0] diff --git a/app/models/champs/multiple_drop_down_list_champ.rb b/app/models/champs/multiple_drop_down_list_champ.rb index ff120ac23..385161f5d 100644 --- a/app/models/champs/multiple_drop_down_list_champ.rb +++ b/app/models/champs/multiple_drop_down_list_champ.rb @@ -1,6 +1,24 @@ class Champs::MultipleDropDownListChamp < Champ before_save :format_before_save + def options? + drop_down_list_options? + end + + def options + drop_down_list_options + end + + def disabled_options + drop_down_list_disabled_options + end + + def enabled_non_empty_options + drop_down_list_enabled_non_empty_options + end + + THRESHOLD_NB_OPTIONS_AS_CHECKBOX = 5 + def search_terms selected_options end @@ -21,6 +39,10 @@ class Champs::MultipleDropDownListChamp < Champ value.present? ? selected_options.join(', ') : nil end + def render_as_checkboxes? + enabled_non_empty_options.size <= THRESHOLD_NB_OPTIONS_AS_CHECKBOX + end + private def format_before_save diff --git a/app/models/dossier.rb b/app/models/dossier.rb index b3241ba37..b1898d2e2 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -701,7 +701,8 @@ class Dossier < ApplicationRecord end def attachments_downloadable? - !PiecesJustificativesService.liste_pieces_justificatives(self).empty? && PiecesJustificativesService.pieces_justificatives_total_size(self) < Dossier::TAILLE_MAX_ZIP + PiecesJustificativesService.liste_pieces_justificatives(self).present? \ + && PiecesJustificativesService.pieces_justificatives_total_size(self) < Dossier::TAILLE_MAX_ZIP end def linked_dossiers_for(instructeur) diff --git a/app/models/drop_down_list.rb b/app/models/drop_down_list.rb index 993bf0e04..e499c1fc2 100644 --- a/app/models/drop_down_list.rb +++ b/app/models/drop_down_list.rb @@ -1,26 +1,8 @@ class DropDownList < ApplicationRecord belongs_to :type_de_champ - before_validation :clean_value - def options result = value.split(/[\r\n]|[\r]|[\n]|[\n\r]/).reject(&:empty?) result.blank? ? [] : [''] + result end - - def disabled_options - options.filter { |v| (v =~ /^--.*--$/).present? } - end - - def multiple - type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) - end - - private - - def clean_value - value = read_attribute(:value) - value = value ? value.split("\r\n").map(&:strip).join("\r\n") : '' - write_attribute(:value, value) - end end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index ca26be603..9887cf77d 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -35,7 +35,7 @@ class TypeDeChamp < ApplicationRecord belongs_to :parent, class_name: 'TypeDeChamp' has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', inverse_of: :parent, dependent: :destroy - store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj + store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj, :drop_down_options delegate :tags_for_template, to: :dynamic_type class WithIndifferentAccess @@ -53,7 +53,6 @@ class TypeDeChamp < ApplicationRecord after_initialize :set_dynamic_type after_create :populate_stable_id before_save :setup_procedure - before_validation :set_default_drop_down_list attr_reader :dynamic_type @@ -83,6 +82,7 @@ class TypeDeChamp < ApplicationRecord before_validation :check_mandatory before_save :remove_piece_justificative_template, if: -> { type_champ_changed? } + before_validation :remove_drop_down_list, if: -> { type_champ_changed? } def valid?(context = nil) super @@ -146,6 +146,10 @@ class TypeDeChamp < ApplicationRecord ]) end + def linked_drop_down_list? + type_champ == TypeDeChamp.type_champs.fetch(:linked_drop_down_list) + end + def exclude_from_view? type_champ == TypeDeChamp.type_champs.fetch(:explication) end @@ -158,6 +162,10 @@ class TypeDeChamp < ApplicationRecord type_champ == TypeDeChamp.type_champs.fetch(:dossier_link) end + def piece_justificative? + type_champ == TypeDeChamp.type_champs.fetch(:piece_justificative) + end + def legacy_number? type_champ == TypeDeChamp.type_champs.fetch(:number) end @@ -183,11 +191,31 @@ class TypeDeChamp < ApplicationRecord end def drop_down_list_value - drop_down_list&.value + if drop_down_list_options.present? + drop_down_list_options.reject(&:empty?).join("\r\n") + else + '' + end end def drop_down_list_value=(value) - self.drop_down_list_attributes = { value: value } + self.drop_down_options = parse_drop_down_list_value(value) + end + + def drop_down_list_options? + drop_down_list_options.any? + end + + def drop_down_list_options + drop_down_options.presence || drop_down_list&.options || [] + end + + def drop_down_list_disabled_options + drop_down_list_options.filter { |v| (v =~ /^--.*--$/).present? } + end + + def drop_down_list_enabled_non_empty_options + (drop_down_list_options - drop_down_list_disabled_options).reject(&:empty?) end def to_typed_id @@ -244,10 +272,10 @@ class TypeDeChamp < ApplicationRecord private - def set_default_drop_down_list - if drop_down_list? && !drop_down_list - self.drop_down_list_attributes = { value: '' } - end + def parse_drop_down_list_value(value) + value = value ? value.split("\r\n").map(&:strip).join("\r\n") : '' + result = value.split(/[\r\n]|[\r]|[\n]|[\n\r]/).reject(&:empty?) + result.blank? ? [] : [''] + result end def setup_procedure @@ -263,8 +291,15 @@ class TypeDeChamp < ApplicationRecord end def remove_piece_justificative_template - if type_champ != TypeDeChamp.type_champs.fetch(:piece_justificative) && piece_justificative_template.attached? + if !piece_justificative? && piece_justificative_template.attached? piece_justificative_template.purge_later end end + + def remove_drop_down_list + if !drop_down_list? + self.drop_down_list = nil + self.drop_down_options = nil + end + end end diff --git a/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb b/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb index 24410c6f6..ca6817c56 100644 --- a/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb +++ b/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb @@ -1,26 +1,9 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBase PRIMARY_PATTERN = /^--(.*)--$/ - delegate :drop_down_list, to: :@type_de_champ - + delegate :drop_down_list_options, to: :@type_de_champ validate :check_presence_of_primary_options - def primary_options - primary_options = unpack_options.map(&:first) - if primary_options.present? - primary_options.unshift('') - end - primary_options - end - - def secondary_options - secondary_options = unpack_options.to_h - if secondary_options.present? - secondary_options[''] = [] - end - secondary_options - end - def tags_for_template tags = super tdc = @type_de_champ @@ -49,16 +32,26 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas tags end - private - - def check_presence_of_primary_options - if !PRIMARY_PATTERN.match?(drop_down_list.options.second) - errors.add(libelle.presence || "La liste", "doit commencer par une entrée de menu primaire de la forme --texte--") + def primary_options + primary_options = unpack_options.map(&:first) + if primary_options.present? + primary_options.unshift('') end + primary_options end + def secondary_options + secondary_options = unpack_options.to_h + if secondary_options.present? + secondary_options[''] = [] + end + secondary_options + end + + private + def unpack_options - _, *options = drop_down_list.options + _, *options = drop_down_list_options chunked = options.slice_before(PRIMARY_PATTERN) chunked.map do |chunk| primary, *secondary = chunk @@ -66,4 +59,10 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas [PRIMARY_PATTERN.match(primary)&.[](1), secondary] end end + + def check_presence_of_primary_options + if !PRIMARY_PATTERN.match?(drop_down_list_options.second) + errors.add(libelle.presence || "La liste", "doit commencer par une entrée de menu primaire de la forme --texte--") + end + end end diff --git a/app/policies/champ_policy.rb b/app/policies/champ_policy.rb index a55efe1a0..a3af2f225 100644 --- a/app/policies/champ_policy.rb +++ b/app/policies/champ_policy.rb @@ -1,4 +1,8 @@ class ChampPolicy < ApplicationPolicy + # Scope for WRITING to a champ. + # + # (If the need for a scope to READ a champ emerges, we can implement another scope + # in this file, following this example: https://github.com/varvet/pundit/issues/368#issuecomment-196111115) class Scope < ApplicationScope def resolve if user.blank? diff --git a/app/services/pieces_justificatives_service.rb b/app/services/pieces_justificatives_service.rb index c58997acc..7b4632b09 100644 --- a/app/services/pieces_justificatives_service.rb +++ b/app/services/pieces_justificatives_service.rb @@ -1,16 +1,10 @@ class PiecesJustificativesService def self.liste_pieces_justificatives(dossier) - pjs_commentaires = dossier.commentaires - .map(&:piece_jointe) + pjs_champs = pjs_for_champs(dossier) + pjs_commentaires = pjs_for_commentaires(dossier) + + (pjs_champs + pjs_commentaires) .filter(&:attached?) - - champs_blocs_repetables = dossier.champs - .filter { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:repetition) } - .flat_map(&:champs) - - pjs_commentaires + champs_pieces_justificatives_with_attachments( - champs_blocs_repetables + dossier.champs - ) end def self.pieces_justificatives_total_size(dossier) @@ -48,10 +42,21 @@ class PiecesJustificativesService private - def self.champs_pieces_justificatives_with_attachments(champs) - champs + def self.pjs_for_champs(dossier) + allowed_champs = dossier.champs + dossier.champs_private + + allowed_child_champs = allowed_champs + .filter { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:repetition) } + .flat_map(&:champs) + + (allowed_champs + allowed_child_champs) .filter { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:piece_justificative) } - .filter { |pj| pj.piece_justificative_file.attached? } .map(&:piece_justificative_file) end + + def self.pjs_for_commentaires(dossier) + dossier + .commentaires + .map(&:piece_jointe) + end end diff --git a/app/views/admin/attestation_templates/show.pdf.prawn b/app/views/admin/attestation_templates/show.pdf.prawn index 399bb68be..a77a6711c 100644 --- a/app/views/admin/attestation_templates/show.pdf.prawn +++ b/app/views/admin/attestation_templates/show.pdf.prawn @@ -28,8 +28,8 @@ logo = @attestation[:logo] signature = @attestation[:signature] prawn_document(margin: [top_margin, right_margin, bottom_margin, left_margin], page_size: page_size) do |pdf| - pdf.font_families.update( 'liberation serif' => { normal: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Regular.ttf' )}) - pdf.font 'liberation serif' + pdf.font_families.update( 'marianne' => { normal: Rails.root.join('lib/prawn/fonts/marianne/marianne-regular.ttf' )}) + pdf.font 'marianne' grey = '555555' black = '333333' @@ -47,13 +47,13 @@ prawn_document(margin: [top_margin, right_margin, bottom_margin, left_margin], p end pdf.fill_color grey - pdf.pad_top(40) { pdf.text "le #{l(created_at, format: '%e %B %Y')}", size: 10, align: :right, character_spacing: -0.5 } + pdf.pad_top(40) { pdf.text "le #{l(created_at, format: '%e %B %Y')}", size: 9, align: :right, character_spacing: -0.5 } pdf.fill_color black - pdf.pad_top(40) { pdf.text title, size: 18, character_spacing: -0.2 } + pdf.pad_top(40) { pdf.text title, size: 14, character_spacing: -0.2 } pdf.fill_color grey - pdf.pad_top(30) { pdf.text body, size: 10, character_spacing: -0.2, align: :justify } + pdf.pad_top(30) { pdf.text body, size: 9, character_spacing: -0.2, align: :justify } if signature.present? pdf.pad_top(40) do diff --git a/app/views/dossiers/dossier_vide.pdf.prawn b/app/views/dossiers/dossier_vide.pdf.prawn index 7ed76a9db..b33924ae3 100644 --- a/app/views/dossiers/dossier_vide.pdf.prawn +++ b/app/views/dossiers/dossier_vide.pdf.prawn @@ -8,7 +8,7 @@ def render_in_2_columns(pdf, label, text) end def format_in_2_lines(pdf, champ, nb_lines = 1) - add_single_line(pdf, champ.libelle, 12, :bold) + add_single_line(pdf, champ.libelle, 9, :bold) add_optionnal_description(pdf, champ) height = 10 * (nb_lines+1) pdf.bounding_box([0, pdf.cursor],:width => 460,:height => height) do @@ -27,7 +27,7 @@ def format_in_2_columns(pdf, label) end def format_with_checkbox(pdf, label, offset = 0) - pdf.font 'liberation serif', size: 12 do + pdf.font 'marianne', size: 9 do pdf.stroke_rectangle [0 + offset, pdf.cursor], 10, 10 pdf.text_box label, at: [15 + offset, pdf.cursor] end @@ -63,7 +63,7 @@ def add_identite_individual(pdf, dossier) end def add_identite_etablissement(pdf, libelle) - add_single_line(pdf, libelle, 12, :bold) + add_single_line(pdf, libelle, 9, :bold) format_in_2_columns(pdf, "SIRET") format_in_2_columns(pdf, "Dénomination") @@ -71,18 +71,18 @@ def add_identite_etablissement(pdf, libelle) end def add_single_line(pdf, libelle, size, style) - pdf.font 'liberation serif', style: style, size: size do + pdf.font 'marianne', style: style, size: size do pdf.text libelle end end def add_title(pdf, title) - add_single_line(pdf, title, 24, :bold) + add_single_line(pdf, title, 20, :bold) pdf.text "\n" end def add_libelle(pdf, champ) - add_single_line(pdf, champ.libelle, 12, :bold) + add_single_line(pdf, champ.libelle, 9, :bold) end def add_explanation(pdf, explanation) @@ -98,7 +98,7 @@ def render_single_champ(pdf, champ) when 'Champs::RepetitionChamp' raise 'There should not be a RepetitionChamp here !' when 'Champs::PieceJustificativeChamp' - add_single_line(pdf, 'Pièce justificative à joindre en complément du dossier', 12, :bold) + add_single_line(pdf, 'Pièce justificative à joindre en complément du dossier', 9, :bold) format_with_checkbox(pdf, champ.libelle) add_optionnal_description(pdf, champ) pdf.text "\n" @@ -116,7 +116,7 @@ def render_single_champ(pdf, champ) format_with_checkbox(pdf, Individual::GENDER_MALE) pdf.text "\n" when 'Champs::HeaderSectionChamp' - add_single_line(pdf, champ.libelle, 18, :bold) + add_single_line(pdf, champ.libelle, 14, :bold) add_optionnal_description(pdf, champ) pdf.text "\n" when 'Champs::ExplicationChamp' @@ -129,7 +129,7 @@ def render_single_champ(pdf, champ) add_libelle(pdf, champ) add_optionnal_description(pdf, champ) add_explanation(pdf, 'Cochez la mention applicable, une seule valeur possible') - champ.drop_down_list.options.reject(&:blank?).each do |option| + champ.options.reject(&:blank?).each do |option| format_with_checkbox(pdf, option) end pdf.text "\n" @@ -137,7 +137,7 @@ def render_single_champ(pdf, champ) add_libelle(pdf, champ) add_optionnal_description(pdf, champ) add_explanation(pdf, 'Cochez la mention applicable, plusieurs valeurs possibles') - champ.drop_down_list.options.reject(&:blank?).each do |option| + champ.options.reject(&:blank?).each do |option| format_with_checkbox(pdf, option) end pdf.text "\n" @@ -175,12 +175,12 @@ def add_champs(pdf, champs) end prawn_document(page_size: "A4") do |pdf| - pdf.font_families.update( 'liberation serif' => { - normal: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Regular.ttf' ), - bold: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Bold.ttf' ), - italic: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Italic.ttf' ), + pdf.font_families.update( 'marianne' => { + normal: Rails.root.join('lib/prawn/fonts/marianne/marianne-regular.ttf' ), + bold: Rails.root.join('lib/prawn/fonts/marianne/marianne-bold.ttf' ), + italic: Rails.root.join('lib/prawn/fonts/marianne/marianne-thin.ttf' ), }) - pdf.font 'liberation serif' + pdf.font 'marianne' pdf.svg IO.read("app/assets/images/header/logo-ds-wide.svg"), width: 300, position: :center pdf.move_down(40) @@ -199,7 +199,7 @@ prawn_document(page_size: "A4") do |pdf| pdf.text "\n" add_title(pdf, 'Formulaire') - add_single_line(pdf, @procedure.description + "\n", 12, :italic) if @procedure.description.present? + add_single_line(pdf, @procedure.description + "\n", 9, :italic) if @procedure.description.present? add_champs(pdf, @dossier.champs) add_page_numbering(pdf) add_procedure(pdf, @dossier) diff --git a/app/views/dossiers/show.pdf.prawn b/app/views/dossiers/show.pdf.prawn index 50f9b7431..366dc6fc6 100644 --- a/app/views/dossiers/show.pdf.prawn +++ b/app/views/dossiers/show.pdf.prawn @@ -1,11 +1,11 @@ require 'prawn/measurement_extensions' def format_in_2_lines(pdf, label, text) - pdf.font 'liberation serif', style: :bold, size: 12 do + pdf.font 'marianne', style: :bold, size: 10 do pdf.text label end - pdf.text text - pdf.text "\n" + pdf.text text, size: 9 + pdf.text "\n", size: 9 end def format_in_2_columns(pdf, label, text) @@ -16,8 +16,8 @@ def format_in_2_columns(pdf, label, text) end def add_title(pdf, title) - title_style = {style: :bold, size: 24} - pdf.font 'liberation serif', title_style do + title_style = {style: :bold, size: 20} + pdf.font 'marianne', title_style do pdf.text title end pdf.text "\n" @@ -83,7 +83,7 @@ def render_single_champ(pdf, champ) when 'Champs::PieceJustificativeChamp' return when 'Champs::HeaderSectionChamp' - pdf.font 'liberation serif', style: :bold, size: 18 do + pdf.font 'marianne', style: :bold, size: 14 do pdf.text champ.libelle end pdf.text "\n" @@ -92,7 +92,7 @@ def render_single_champ(pdf, champ) when 'Champs::CarteChamp' format_in_2_lines(pdf, champ.libelle, champ.to_feature_collection.to_json) when 'Champs::SiretChamp' - pdf.font 'liberation serif', style: :bold, size: 12 do + pdf.font 'marianne', style: :bold, size: 9 do pdf.text champ.libelle end pdf.text " - SIRET: #{champ.to_s}" @@ -130,8 +130,8 @@ def add_message(pdf, message) end pdf.text "#{sender}, #{format_date(message.created_at)}", style: :bold - pdf.text ActionView::Base.full_sanitizer.sanitize(message.body) - pdf.text "\n" + pdf.text ActionView::Base.full_sanitizer.sanitize(message.body), size: 9 + pdf.text "\n", size: 9 end def add_avis(pdf, avis) @@ -159,11 +159,11 @@ def add_etats_dossier(pdf, dossier) end prawn_document(page_size: "A4") do |pdf| - pdf.font_families.update( 'liberation serif' => { - normal: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Regular.ttf' ), - bold: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Bold.ttf' ), + pdf.font_families.update( 'marianne' => { + normal: Rails.root.join('lib/prawn/fonts/marianne/marianne-regular.ttf' ), + bold: Rails.root.join('lib/prawn/fonts/marianne/marianne-bold.ttf' ), }) - pdf.font 'liberation serif' + pdf.font 'marianne' pdf.svg IO.read("app/assets/images/header/logo-ds-wide.svg"), width: 300, position: :center pdf.move_down(40) diff --git a/app/views/instructeurs/dossiers/_header_actions.html.haml b/app/views/instructeurs/dossiers/_header_actions.html.haml index 62b2e0add..e83bff6ff 100644 --- a/app/views/instructeurs/dossiers/_header_actions.html.haml +++ b/app/views/instructeurs/dossiers/_header_actions.html.haml @@ -12,7 +12,7 @@ %li = link_to "Export GeoJSON", geo_data_instructeur_dossier_path(dossier.procedure, dossier), target: "_blank", rel: "noopener", class: "menu-item menu-link" -- if !PiecesJustificativesService.liste_pieces_justificatives(dossier).empty? +- if PiecesJustificativesService.liste_pieces_justificatives(dossier).present? %span.dropdown.print-menu-opener %button.button.dropdown-button.icon-only %span.icon.attached diff --git a/app/views/shared/dossiers/editable_champs/_drop_down_list.html.haml b/app/views/shared/dossiers/editable_champs/_drop_down_list.html.haml index 05b938cfc..a2c38f0fc 100644 --- a/app/views/shared/dossiers/editable_champs/_drop_down_list.html.haml +++ b/app/views/shared/dossiers/editable_champs/_drop_down_list.html.haml @@ -1,5 +1,14 @@ -- if champ.drop_down_list && champ.drop_down_list.options.any? - = form.select :value, - champ.drop_down_list.options, - disabled: champ.drop_down_list.disabled_options, - required: champ.mandatory? +- if champ.options? + - if champ.render_as_radios? + %fieldset.radios + %legend.mandatory-explanation + Sélectionnez une des valeurs + - champ.enabled_non_empty_options.each do |option| + %label + = form.radio_button :value, option + = option + - else + = form.select :value, + champ.options, + disabled: champ.disabled_options, + required: champ.mandatory? diff --git a/app/views/shared/dossiers/editable_champs/_linked_drop_down_list.html.haml b/app/views/shared/dossiers/editable_champs/_linked_drop_down_list.html.haml index 259aa3bc1..569f03a85 100644 --- a/app/views/shared/dossiers/editable_champs/_linked_drop_down_list.html.haml +++ b/app/views/shared/dossiers/editable_champs/_linked_drop_down_list.html.haml @@ -1,4 +1,4 @@ -- if champ.drop_down_list && champ.drop_down_list.options.any? +- if champ.options? = form.select :primary_value, champ.primary_options, { required: champ.mandatory? }, diff --git a/app/views/shared/dossiers/editable_champs/_multiple_drop_down_list.html.haml b/app/views/shared/dossiers/editable_champs/_multiple_drop_down_list.html.haml index efbb7dda2..77e194186 100644 --- a/app/views/shared/dossiers/editable_champs/_multiple_drop_down_list.html.haml +++ b/app/views/shared/dossiers/editable_champs/_multiple_drop_down_list.html.haml @@ -1,7 +1,15 @@ -- if champ.drop_down_list && champ.drop_down_list.options.any? - = form.select :value, - champ.drop_down_list.options, - { selected: champ.selected_options, - disabled: champ.drop_down_list.disabled_options }, - multiple: true, - class: 'select2' +- if champ.options? + - if champ.render_as_checkboxes? + - champ.enabled_non_empty_options.each do |option| + .editable-champ.editable-champ-checkbox + %label + = form.check_box :value, { multiple: true, checked: champ&.value&.include?(option) }, option, nil + = option + - else + = form.select :value, + champ.options, + { selected: champ.selected_options, + disabled: champ.disabled_options }, + multiple: true, + class: 'select2' + diff --git a/lib/prawn/fonts/marianne/marianne-bold.ttf b/lib/prawn/fonts/marianne/marianne-bold.ttf new file mode 100644 index 000000000..ffa9711dd Binary files /dev/null and b/lib/prawn/fonts/marianne/marianne-bold.ttf differ diff --git a/lib/prawn/fonts/marianne/marianne-regular.ttf b/lib/prawn/fonts/marianne/marianne-regular.ttf new file mode 100644 index 000000000..d192b705b Binary files /dev/null and b/lib/prawn/fonts/marianne/marianne-regular.ttf differ diff --git a/lib/prawn/fonts/marianne/marianne-thin.ttf b/lib/prawn/fonts/marianne/marianne-thin.ttf new file mode 100644 index 000000000..301b3c668 Binary files /dev/null and b/lib/prawn/fonts/marianne/marianne-thin.ttf differ diff --git a/lib/tasks/deployment/20200618121241_drop_down_list_options_to_json.rake b/lib/tasks/deployment/20200618121241_drop_down_list_options_to_json.rake new file mode 100644 index 000000000..a96758e98 --- /dev/null +++ b/lib/tasks/deployment/20200618121241_drop_down_list_options_to_json.rake @@ -0,0 +1,25 @@ +namespace :after_party do + desc 'Deployment task: drop_down_list_options_to_json' + task drop_down_list_options_to_json: :environment do + puts "Running deploy task 'drop_down_list_options_to_json'" + + types_de_champ = TypeDeChamp.joins(:drop_down_list).where(type_champ: [ + TypeDeChamp.type_champs.fetch(:drop_down_list), + TypeDeChamp.type_champs.fetch(:multiple_drop_down_list), + TypeDeChamp.type_champs.fetch(:linked_drop_down_list) + ]) + progress = ProgressReport.new(types_de_champ.count) + types_de_champ.find_each do |type_de_champ| + type_de_champ.drop_down_list_value = type_de_champ.drop_down_list_value + if type_de_champ.save + type_de_champ.drop_down_list.destroy + end + progress.inc + end + progress.finish + + # Update task as completed. If you remove the line below, the task will + # run with every deploy (or every time you call after_party:run). + AfterParty::TaskRecord.create version: '20200618121241' + end +end diff --git a/spec/factories/drop_down_list.rb b/spec/factories/drop_down_list.rb deleted file mode 100644 index 5cc47a7fa..000000000 --- a/spec/factories/drop_down_list.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :drop_down_list do - value { "val1\r\nval2\r\n--separateur--\r\nval3" } - end -end diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index 7fcc26f39..e111638d0 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -233,6 +233,8 @@ FactoryBot.define do end build(:"type_de_champ_#{type_champ}", mandatory: true, libelle: libelle, order_place: index) end + procedure.types_de_champ << build(:type_de_champ_drop_down_list, :long, mandatory: true, libelle: 'simple_choice_drop_down_list_long') + procedure.types_de_champ << build(:type_de_champ_multiple_drop_down_list, :long, mandatory: true, libelle: 'multiple_choice_drop_down_list_long') end end diff --git a/spec/factories/type_de_champ.rb b/spec/factories/type_de_champ.rb index 597d84c9e..6aa9ccd35 100644 --- a/spec/factories/type_de_champ.rb +++ b/spec/factories/type_de_champ.rb @@ -52,15 +52,21 @@ FactoryBot.define do factory :type_de_champ_drop_down_list do libelle { 'Menu déroulant' } type_champ { TypeDeChamp.type_champs.fetch(:drop_down_list) } - drop_down_list { create(:drop_down_list) } + drop_down_list_value { "val1\r\nval2\r\n--separateur--\r\nval3" } + trait :long do + drop_down_list_value { "alpha\r\nbravo\r\n--separateur--\r\ncharly\r\ndelta\r\necho\r\nfox-trot\r\ngolf" } + end end factory :type_de_champ_multiple_drop_down_list do type_champ { TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) } - drop_down_list { create(:drop_down_list) } + drop_down_list_value { "val1\r\nval2\r\n--separateur--\r\nval3" } + trait :long do + drop_down_list_value { "alpha\r\nbravo\r\n--separateur--\r\ncharly\r\ndelta\r\necho\r\nfox-trot\r\ngolf" } + end end factory :type_de_champ_linked_drop_down_list do type_champ { TypeDeChamp.type_champs.fetch(:linked_drop_down_list) } - drop_down_list { create(:drop_down_list, value: "--primary--\nsecondary\n") } + drop_down_list_value { "--primary--\nsecondary\n" } end factory :type_de_champ_pays do type_champ { TypeDeChamp.type_champs.fetch(:pays) } diff --git a/spec/features/new_administrateur/types_de_champ_spec.rb b/spec/features/new_administrateur/types_de_champ_spec.rb index 4ef40f750..b460e026a 100644 --- a/spec/features/new_administrateur/types_de_champ_spec.rb +++ b/spec/features/new_administrateur/types_de_champ_spec.rb @@ -139,7 +139,7 @@ feature 'As an administrateur I can edit types de champ', js: true do fill_in 'champ-0-libelle', with: 'Libellé de champ menu déroulant', fill_options: { clear: :backspace } fill_in 'champ-0-drop_down_list_value', with: 'Un menu', fill_options: { clear: :backspace } - wait_until { procedure.types_de_champ.first.drop_down_list&.value == 'Un menu' } + wait_until { procedure.types_de_champ.first.drop_down_list_options == ['', 'Un menu'] } expect(page).to have_content('Formulaire enregistré') page.refresh diff --git a/spec/features/users/brouillon_spec.rb b/spec/features/users/brouillon_spec.rb index 8b6a02d2d..d9c126487 100644 --- a/spec/features/users/brouillon_spec.rb +++ b/spec/features/users/brouillon_spec.rb @@ -21,9 +21,12 @@ feature 'The user' do fill_in('email', with: 'loulou@yopmail.com') fill_in('phone', with: '1234567890') choose('Non') - select('val2', from: form_id_for('simple_drop_down_list')) - select('val1', from: form_id_for('multiple_drop_down_list')) - select('val3', from: form_id_for('multiple_drop_down_list')) + choose('val2') + check('val1') + check('val3') + select('bravo', from: form_id_for('simple_choice_drop_down_list_long')) + select('alpha', from: form_id_for('multiple_choice_drop_down_list_long')) + select('charly', from: form_id_for('multiple_choice_drop_down_list_long')) select('AUSTRALIE', from: 'pays') select_champ_geo('regions', 'Ma', 'Martinique') @@ -55,6 +58,8 @@ feature 'The user' do expect(champ_value_for('phone')).to eq('1234567890') expect(champ_value_for('yes_no')).to eq('false') expect(champ_value_for('simple_drop_down_list')).to eq('val2') + expect(champ_value_for('simple_choice_drop_down_list_long')).to eq('bravo') + expect(JSON.parse(champ_value_for('multiple_choice_drop_down_list_long'))).to match(['alpha', 'charly']) expect(JSON.parse(champ_value_for('multiple_drop_down_list'))).to match(['val1', 'val3']) expect(champ_value_for('pays')).to eq('AUSTRALIE') expect(champ_value_for('regions')).to eq('Martinique') @@ -76,8 +81,11 @@ feature 'The user' do expect(page).to have_field('email', with: 'loulou@yopmail.com') expect(page).to have_field('phone', with: '1234567890') expect(page).to have_checked_field('Non') - expect(page).to have_selected_value('simple_drop_down_list', selected: 'val2') - expect(page).to have_selected_value('multiple_drop_down_list', selected: ['val1', 'val3']) + expect(page).to have_checked_field('val2') + expect(page).to have_checked_field('val1') + expect(page).to have_checked_field('val3') + expect(page).to have_selected_value('simple_choice_drop_down_list_long', selected: 'bravo') + expect(page).to have_selected_value('multiple_choice_drop_down_list_long', selected: ['alpha', 'charly']) expect(page).to have_selected_value('pays', selected: 'AUSTRALIE') expect(page).to have_selected_value('regions', selected: 'Martinique') expect(page).to have_selected_value('departements', selected: '02 - Aisne') diff --git a/spec/features/users/linked_dropdown_spec.rb b/spec/features/users/linked_dropdown_spec.rb index 97c7e46ec..efbe56099 100644 --- a/spec/features/users/linked_dropdown_spec.rb +++ b/spec/features/users/linked_dropdown_spec.rb @@ -13,8 +13,7 @@ feature 'linked dropdown lists' do Secondary 2.3 END_OF_LIST end - let(:drop_down_list) { create(:drop_down_list, value: list_items) } - let(:type_de_champ) { create(:type_de_champ_linked_drop_down_list, libelle: 'linked dropdown', drop_down_list: drop_down_list) } + let(:type_de_champ) { create(:type_de_champ_linked_drop_down_list, libelle: 'linked dropdown', drop_down_list_value: list_items) } let!(:procedure) do p = create(:procedure, :published, :for_individual) diff --git a/spec/jobs/api_entreprise/effectifs_job_spec.rb b/spec/jobs/api_entreprise/effectifs_job_spec.rb index 1aaed9309..458dcf06e 100644 --- a/spec/jobs/api_entreprise/effectifs_job_spec.rb +++ b/spec/jobs/api_entreprise/effectifs_job_spec.rb @@ -6,7 +6,7 @@ RSpec.describe ApiEntreprise::EffectifsJob, type: :job do let(:procedure_id) { procedure.id } let(:now) { Time.zone.local(2020, 3, 12) } let(:annee) { "2020" } - let(:mois) { "04" } + let(:mois) { "05" } let(:body) { File.read('spec/fixtures/files/api_entreprise/effectifs.json') } let(:status) { 200 } diff --git a/spec/lib/active_storage/downloadable_file_spec.rb b/spec/lib/active_storage/downloadable_file_spec.rb index 8a4ab048e..5bf1f8956 100644 --- a/spec/lib/active_storage/downloadable_file_spec.rb +++ b/spec/lib/active_storage/downloadable_file_spec.rb @@ -13,7 +13,15 @@ describe ActiveStorage::DownloadableFile do dossier.champs << create(:champ, :piece_justificative, :with_piece_justificative_file) end - it { expect(list.length).to be 1 } + it { expect(list.length).to eq 1 } + end + + context 'when there is a private piece_justificative' do + before do + dossier.champs_private << create(:champ, :piece_justificative, :with_piece_justificative_file, private: true) + end + + it { expect(list.length).to eq 1 } end context 'when there is a repetition bloc' do @@ -21,7 +29,7 @@ describe ActiveStorage::DownloadableFile do let(:dossier) { create(:dossier, :en_construction, champs: [champ]) } it 'should have 4 piece_justificatives' do - expect(list.size).to eq(4) + expect(list.size).to eq 4 end end @@ -29,14 +37,14 @@ describe ActiveStorage::DownloadableFile do let(:commentaire) { create(:commentaire) } let(:dossier) { commentaire.dossier } - it { expect(list.length).to be 0 } + it { expect(list.length).to eq 0 } end context 'when there is a message with an attachment' do let(:commentaire) { create(:commentaire, :with_file) } let(:dossier) { commentaire.dossier } - it { expect(list.length).to be 1 } + it { expect(list.length).to eq 1 } end end end diff --git a/spec/models/champs/linked_drop_down_list_champ_spec.rb b/spec/models/champs/linked_drop_down_list_champ_spec.rb index a148f7371..9d0977716 100644 --- a/spec/models/champs/linked_drop_down_list_champ_spec.rb +++ b/spec/models/champs/linked_drop_down_list_champ_spec.rb @@ -62,12 +62,12 @@ describe Champs::LinkedDropDownListChamp do end describe '#mandatory_and_blank' do - let(:drop_down_list) { build(:drop_down_list, value: "--Primary--\nSecondary") } + let(:value) { "--Primary--\nSecondary" } subject { described_class.new(type_de_champ: type_de_champ) } context 'when the champ is not mandatory' do - let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, drop_down_list: drop_down_list) } + let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, drop_down_list_value: value) } it 'blank is fine' do is_expected.not_to be_mandatory_and_blank @@ -75,7 +75,7 @@ describe Champs::LinkedDropDownListChamp do end context 'when the champ is mandatory' do - let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, mandatory: true, drop_down_list: drop_down_list) } + let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, mandatory: true, drop_down_list_value: value) } context 'when there is no value' do it { is_expected.to be_mandatory_and_blank } @@ -95,7 +95,7 @@ describe Champs::LinkedDropDownListChamp do end context 'when there is nothing to select for the secondary value' do - let(:drop_down_list) { build(:drop_down_list, value: "--A--\nAbbott\nAbelard\n--B--\n--C--\nCynthia") } + let(:value) { "--A--\nAbbott\nAbelard\n--B--\n--C--\nCynthia" } before { subject.primary_value = 'B' } it { is_expected.not_to be_mandatory_and_blank } diff --git a/spec/models/drop_down_list_spec.rb b/spec/models/drop_down_list_spec.rb deleted file mode 100644 index 45f31ab1d..000000000 --- a/spec/models/drop_down_list_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -describe DropDownList do - let(:dropdownlist) { create :drop_down_list, value: value } - - describe '#options' do - let(:value) do - <<~EOS - Cohésion sociale - Dév.Eco / Emploi - Cadre de vie / Urb. - Pilotage / Ingénierie - EOS - end - - it { expect(dropdownlist.options).to eq ['', 'Cohésion sociale', 'Dév.Eco / Emploi', 'Cadre de vie / Urb.', 'Pilotage / Ingénierie'] } - - context 'when one value is empty' do - let(:value) do - <<~EOS - Cohésion sociale - Cadre de vie / Urb. - Pilotage / Ingénierie - EOS - end - - it { expect(dropdownlist.options).to eq ['', 'Cohésion sociale', 'Cadre de vie / Urb.', 'Pilotage / Ingénierie'] } - end - end - - describe 'disabled_options' do - let(:value) do - <<~EOS - tip - --top-- - --troupt-- - ouaich - EOS - end - - it { expect(dropdownlist.disabled_options).to match(['--top--', '--troupt--']) } - end -end diff --git a/spec/models/type_de_champ_shared_example.rb b/spec/models/type_de_champ_shared_example.rb index 804ac127a..2c0ba51ae 100644 --- a/spec/models/type_de_champ_shared_example.rb +++ b/spec/models/type_de_champ_shared_example.rb @@ -187,4 +187,44 @@ shared_examples 'type_de_champ_spec' do end end end + + describe '#drop_down_list_options' do + let(:value) do + <<~EOS + Cohésion sociale + Dév.Eco / Emploi + Cadre de vie / Urb. + Pilotage / Ingénierie + EOS + end + let(:type_de_champ) { create(:type_de_champ_drop_down_list, drop_down_list_value: value) } + + it { expect(type_de_champ.drop_down_list_options).to eq ['', 'Cohésion sociale', 'Dév.Eco / Emploi', 'Cadre de vie / Urb.', 'Pilotage / Ingénierie'] } + + context 'when one value is empty' do + let(:value) do + <<~EOS + Cohésion sociale + Cadre de vie / Urb. + Pilotage / Ingénierie + EOS + end + + it { expect(type_de_champ.drop_down_list_options).to eq ['', 'Cohésion sociale', 'Cadre de vie / Urb.', 'Pilotage / Ingénierie'] } + end + end + + describe 'disabled_options' do + let(:value) do + <<~EOS + tip + --top-- + --troupt-- + ouaich + EOS + end + let(:type_de_champ) { create(:type_de_champ_drop_down_list, drop_down_list_value: value) } + + it { expect(type_de_champ.drop_down_list_disabled_options).to match(['--top--', '--troupt--']) } + end end diff --git a/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb b/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb index de7323727..11b3291c8 100644 --- a/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb +++ b/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb @@ -1,6 +1,5 @@ describe TypesDeChamp::LinkedDropDownListTypeDeChamp do - let(:drop_down_list) { build(:drop_down_list, value: menu_options) } - let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, drop_down_list: drop_down_list) } + let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, drop_down_list_value: menu_options) } subject { type_de_champ.dynamic_type }