Merge pull request #3240 from betagouv/values

Champ values
This commit is contained in:
gregoirenovel 2019-01-08 12:42:44 +01:00 committed by GitHub
commit 531feb3515
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 197 additions and 307 deletions

View file

@ -9,25 +9,4 @@ module ChampHelper
raw(champ.to_render_data.to_json)
# rubocop:enable Rails/OutputSafety
end
def formatted_value(champ)
value = champ.value
type = champ.type_champ
if type == TypeDeChamp.type_champs.fetch(:date) && value.present?
Date.parse(value).strftime("%d/%m/%Y")
elsif type.in? [TypeDeChamp.type_champs.fetch(:checkbox), TypeDeChamp.type_champs.fetch(:engagement)]
value == 'on' ? 'Oui' : 'Non'
elsif type == TypeDeChamp.type_champs.fetch(:yes_no)
if value == 'true'
'Oui'
elsif value == 'false'
'Non'
end
elsif type == TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) && value.present?
JSON.parse(value).join(', ')
else
value
end
end
end

View file

@ -1,12 +1,16 @@
module DossierLinkHelper
def dossier_linked_path(gestionnaire, dossier)
if dossier.procedure.gestionnaires.include?(gestionnaire)
gestionnaire_dossier_path(dossier.procedure, dossier)
else
avis = dossier.avis.find_by(gestionnaire: gestionnaire)
if avis.present?
gestionnaire_avis_path(avis)
def dossier_linked_path(user, dossier)
if user.is_a?(Gestionnaire)
if dossier.procedure.gestionnaires.include?(user)
gestionnaire_dossier_path(dossier.procedure, dossier)
else
avis = dossier.avis.find_by(gestionnaire: user)
if avis.present?
gestionnaire_avis_path(avis)
end
end
elsif user.owns_or_invite?(dossier)
dossier_path(dossier)
end
end
end

View file

@ -40,32 +40,18 @@ class Champ < ApplicationRecord
end
def to_s
if value.present?
string_value
else
''
end
value.present? ? value.to_s : ''
end
def for_export
if value.present?
value_for_export
else
nil
end
value.presence
end
def for_api
value
end
def main_value_name
:value
end
private
def string_value
value.to_s
end
def value_for_export
value
end
end

View file

@ -88,4 +88,8 @@ class Champs::CarteChamp < Champ
)
end
end
def for_api
geo_json&.to_json
end
end

View file

@ -6,6 +6,14 @@ class Champs::CheckboxChamp < Champ
end
def to_s
value == 'on' ? 'oui' : 'non'
value == 'on' ? 'Oui' : 'Non'
end
def for_export
value == 'on' ? 'on' : 'off'
end
def for_api
value == 'on' ? 'on' : 'off'
end
end

View file

@ -5,6 +5,10 @@ class Champs::DateChamp < Champ
# Text search is pretty useless for dates so were not including these champs
end
def to_s
value.present? ? Date.parse(value).strftime('%d/%m/%Y') : ""
end
private
def format_before_save
@ -15,8 +19,4 @@ class Champs::DateChamp < Champ
nil
end
end
def string_value
Date.parse(value).strftime('%d/%m/%Y')
end
end

View file

@ -1,7 +1,17 @@
class Champs::DecimalNumberChamp < Champ
validates :value, numericality: { allow_nil: true, allow_blank: true }
def value_for_export
value.to_f
def for_export
processed_value
end
def for_api
processed_value
end
private
def processed_value
value&.to_f
end
end

View file

@ -1,7 +1,2 @@
class Champs::EngagementChamp < Champs::CheckboxChamp
def search_terms
if value == 'on'
[libelle]
end
end
end

View file

@ -1,7 +1,17 @@
class Champs::IntegerNumberChamp < Champ
validates :value, numericality: { only_integer: true, allow_nil: true, allow_blank: true }
def value_for_export
value.to_i
def for_export
processed_value
end
def for_api
processed_value
end
private
def processed_value
value&.to_i
end
end

View file

@ -29,8 +29,16 @@ class Champs::LinkedDropDownListChamp < Champ
:primary_value
end
def for_display
string_value
def to_s
value.present? ? [primary_value, secondary_value].compact.join(' / ') : ""
end
def for_export
value.present? ? "#{primary_value || ''};#{secondary_value || ''}" : nil
end
def for_api
value.present? ? { primary: primary_value, secondary: secondary_value } : nil
end
def mandatory_and_blank?
@ -43,14 +51,6 @@ class Champs::LinkedDropDownListChamp < Champ
private
def string_value
[primary_value, secondary_value].compact.join(' / ')
end
def value_for_export
"#{primary_value || ''};#{secondary_value || ''}"
end
def pack_value(primary, secondary)
self.value = JSON.generate([primary, secondary])
end

View file

@ -2,7 +2,19 @@ class Champs::MultipleDropDownListChamp < Champ
before_save :format_before_save
def search_terms
drop_down_list.selected_options_without_decorator(self)
selected_options
end
def selected_options
value.blank? ? [] : JSON.parse(value)
end
def to_s
selected_options.join(', ')
end
def for_export
value.present? ? selected_options.join(', ') : nil
end
private
@ -18,12 +30,4 @@ class Champs::MultipleDropDownListChamp < Champ
end
end
end
def string_value
drop_down_list.selected_options_without_decorator(self).join(', ')
end
def value_for_export
drop_down_list.selected_options_without_decorator(self).join(', ')
end
end

View file

@ -48,6 +48,10 @@ class Champs::PieceJustificativeChamp < Champ
errors
end
def for_api
Rails.application.routes.url_helpers.url_for(piece_justificative_file)
end
private
def create_virus_scan

View file

@ -1,7 +1,5 @@
class Champs::TextareaChamp < Champs::TextChamp
private
def value_for_export
ActionView::Base.full_sanitizer.sanitize(value)
def for_export
value.present? ? ActionView::Base.full_sanitizer.sanitize(value) : nil
end
end

View file

@ -6,12 +6,20 @@ class Champs::YesNoChamp < Champs::CheckboxChamp
end
def to_s
value_for_export
processed_value
end
def for_export
processed_value
end
def for_api
processed_value
end
private
def value_for_export
value == 'true' ? 'oui' : 'non'
def processed_value
value == 'true' ? 'Oui' : 'Non'
end
end

View file

@ -10,10 +10,6 @@ class DropDownList < ApplicationRecord
options.select { |v| (v =~ /^--.*--$/).present? }
end
def selected_options_without_decorator(champ)
champ.value.blank? ? [] : multiple ? JSON.parse(champ.value) : [champ.value]
end
def multiple
type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
end

View file

@ -13,28 +13,8 @@ class ChampSerializer < ActiveModel::Serializer
case object
when GeoArea
object.geometry
when Champs::CarteChamp
if object.geo_json.present?
object.geo_json.to_json
end
when Champs::DecimalNumberChamp
if object.value.present?
object.value.to_f
end
when Champs::IntegerNumberChamp
if object.value.present?
object.value.to_i
end
when Champs::LinkedDropDownListChamp
if object.value.present?
{ primary: object.primary_value, secondary: object.secondary_value }
end
when Champs::PieceJustificativeChamp
if object.piece_justificative_file.attached?
url_for(object.piece_justificative_file)
end
else
object.value
object.for_api
end
end

View file

@ -120,11 +120,9 @@ class ProcedureExportService
def etablissements_table_data
@etablissements = @dossiers.flat_map do |dossier|
dossier.champs.select do |champ|
champ.is_a?(Champs::SiretChamp)
end + dossier.champs_private.select do |champ|
champ.is_a?(Champs::SiretChamp)
end
[dossier.champs, dossier.champs_private]
.flatten
.select { |champ| champ.is_a?(Champs::SiretChamp) }
end.map(&:etablissement).compact
if @etablissements.any?
@ -139,22 +137,13 @@ class ProcedureExportService
end
def dossiers_headers
headers = ATTRIBUTES.map do |key|
label_for_export(key.to_s)
end
headers += @procedure.types_de_champ.reject(&:exclude_from_export?).map do |champ|
label_for_export(champ.libelle)
end
headers += @procedure.types_de_champ_private.reject(&:exclude_from_export?).map do |champ|
label_for_export(champ.libelle)
end
headers += ETABLISSEMENT_ATTRIBUTES.map do |key|
label_for_export("etablissement.#{key}")
end
headers += ENTREPRISE_ATTRIBUTES.map do |key|
label_for_export("entreprise.#{key}")
end
headers
headers = ATTRIBUTES.map(&:to_s) +
@procedure.types_de_champ.reject(&:exclude_from_export?).map(&:libelle) +
@procedure.types_de_champ_private.reject(&:exclude_from_export?).map(&:libelle) +
ETABLISSEMENT_ATTRIBUTES.map { |key| "etablissement.#{key}" } +
ENTREPRISE_ATTRIBUTES.map { |key| "entreprise.#{key}" }
headers.map { |header| label_for_export(header) }
end
def dossiers_data
@ -183,37 +172,28 @@ class ProcedureExportService
dossier.read_attribute(key)
end
end
values = normalize_values(values)
values += dossier.champs.reject(&:exclude_from_export?).map do |champ|
value_for_export(champ)
end
values += dossier.champs_private.reject(&:exclude_from_export?).map do |champ|
value_for_export(champ)
end
values += etablissement_data(dossier.etablissement)
values
normalize_values(values) +
dossier.champs.reject(&:exclude_from_export?).map(&:for_export) +
dossier.champs_private.reject(&:exclude_from_export?).map(&:for_export) +
etablissement_data(dossier.etablissement)
end
end
def etablissements_headers
headers = [:dossier_id, :libelle]
headers += ETABLISSEMENT_ATTRIBUTES.map do |key|
label_for_export("etablissement.#{key}")
end
headers += ENTREPRISE_ATTRIBUTES.map do |key|
label_for_export("entreprise.#{key}")
end
headers
headers = ["dossier_id", "libelle"] +
ETABLISSEMENT_ATTRIBUTES.map { |key| "etablissement.#{key}" } +
ENTREPRISE_ATTRIBUTES.map { |key| "entreprise.#{key}" }
headers.map { |header| label_for_export(header) }
end
def etablissements_data
@etablissements.map do |etablissement|
data = [
[
etablissement.champ.dossier_id,
label_for_export(etablissement.champ.libelle).to_s
]
data + etablissement_data(etablissement)
] + etablissement_data(etablissement)
end
end
@ -245,10 +225,6 @@ class ProcedureExportService
label.parameterize.underscore.to_sym
end
def value_for_export(champ)
champ.for_export
end
def normalize_values(values)
values.map do |value|
case value

View file

@ -33,14 +33,9 @@
%h2 Annotations privées
- if @dossier.champs_private.present?
%table
- @dossier.champs_private.each do |champ|
%tr
%th
= champ.libelle
%td
= champ.value
- champs_annotations_privees = @dossier.champs_private
- if champs_annotations_privees.any?
= render partial: "shared/dossiers/champs", locals: { champs: champs_annotations_privees, dossier: @dossier, demande_seen_at: nil, profile: 'instructeur' }
- else
Aucune annotation privée

View file

@ -1,3 +1,4 @@
.carte{ data: { geo: geo_data(champ) } }
.geo-areas
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, error: false }
- if champ.to_s.present?
.carte{ data: { geo: geo_data(champ) } }
.geo-areas
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, error: false }

View file

@ -0,0 +1,11 @@
- dossier = Dossier.includes(:procedure).find_by(id: champ.to_s)
- if dossier
- path = dossier_linked_path(current_gestionnaire || current_user, dossier)
- if path.present?
= link_to("Dossier nº #{dossier.id}", path, target: '_blank')
- else
Dossier nº #{dossier.id}
%br
= sanitize(dossier.text_summary)
- else
Pas de dossier associé

View file

@ -0,0 +1,5 @@
- if champ.to_s.present?
%ul
- champ.to_s.split(", ").each do |item|
%li
= item

View file

@ -0,0 +1,5 @@
- pj = champ.piece_justificative_file
- if pj.attached?
= render partial: "shared/champs/piece_justificative/pj_link", locals: { champ: champ, user_can_upload: false }
- else
Pièce justificative non fournie

View file

@ -0,0 +1,2 @@
- if champ.etablissement.present?
= render partial: "shared/dossiers/identite_entreprise", locals: { etablissement: champ.etablissement, profile: profile }

View file

@ -0,0 +1 @@
= simple_format(champ.to_s)

View file

@ -2,74 +2,30 @@
%tbody
- champs.reject(&:exclude_from_view?).each do |c|
%tr
- value = formatted_value(c)
- case c.type_champ
- when TypeDeChamp.type_champs.fetch(:header_section)
- if c.type_champ == TypeDeChamp.type_champs.fetch(:header_section)
%th.header-section{ colspan: 3 }
= c.libelle
- when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
%th.libelle
= "#{c.libelle} :"
%td.rich-text
- if value.present?
%ul
- value.split(", ").each do |item|
%li
= item
- when TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
%th.libelle
= "#{c.libelle} :"
%td= c.for_display
- when TypeDeChamp.type_champs.fetch(:dossier_link)
%th.libelle
= "#{c.libelle} :"
%td.rich-text
- dossier = Dossier.includes(:procedure).find_by(id: value)
- if dossier
- path = dossier_linked_path(current_gestionnaire, dossier)
- if path.present?
= link_to("Dossier nº #{dossier.id}", path, target: '_blank')
- else
Dossier nº #{dossier.id}
%br
= sanitize(dossier.text_summary)
- else
Pas de dossier associé
- when TypeDeChamp.type_champs.fetch(:piece_justificative)
%th.libelle
= "#{c.libelle} :"
%td.rich-text
- pj = c.piece_justificative_file
- if pj.attached?
= render partial: "shared/champs/piece_justificative/pj_link", locals: { champ: c, user_can_upload: false }
- else
Pièce justificative non fournie
- when TypeDeChamp.type_champs.fetch(:textarea)
%th.libelle
= "#{c.libelle} :"
%td.rich-text
%span{ class: highlight_if_unseen_class(demande_seen_at, c.updated_at) }
= simple_format(value)
- when TypeDeChamp.type_champs.fetch(:siret)
%th.libelle
= "#{c.libelle} :"
%td.rich-text
%span{ class: highlight_if_unseen_class(demande_seen_at, c.updated_at) }
- if c.etablissement.present?
= render partial: "shared/dossiers/identite_entreprise", locals: { etablissement: c.etablissement, profile: profile }
- when TypeDeChamp.type_champs.fetch(:carte)
%th.libelle
= "#{c.libelle} :"
%td.rich-text
%span{ class: highlight_if_unseen_class(demande_seen_at, c.updated_at) }
- if value.present?
= render partial: "shared/champs/carte/show", locals: { champ: c }
- else
%th.libelle
= "#{c.libelle} :"
%td.rich-text
%span{ class: highlight_if_unseen_class(demande_seen_at, c.updated_at) }
= sanitize(value)
- case c.type_champ
- when TypeDeChamp.type_champs.fetch(:carte)
= render partial: "shared/champs/carte/show", locals: { champ: c }
- when TypeDeChamp.type_champs.fetch(:dossier_link)
= render partial: "shared/champs/dossier_link/show", locals: { champ: c }
- when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
= render partial: "shared/champs/multiple_drop_down_list/show", locals: { champ: c }
- when TypeDeChamp.type_champs.fetch(:piece_justificative)
= render partial: "shared/champs/piece_justificative/show", locals: { champ: c }
- when TypeDeChamp.type_champs.fetch(:siret)
= render partial: "shared/champs/siret/show", locals: { champ: c, profile: profile }
- when TypeDeChamp.type_champs.fetch(:textarea)
= render partial: "shared/champs/text_area/show", locals: { champ: c }
- else
= sanitize(c.to_s)
- if c.type_champ != TypeDeChamp.type_champs.fetch(:header_section)
%td.updated-at
%span{ class: highlight_if_unseen_class(demande_seen_at, c.updated_at) }

View file

@ -1,7 +1,7 @@
- if champ.drop_down_list && champ.drop_down_list.options.any?
= form.select :value,
champ.drop_down_list.options,
{ selected: champ.drop_down_list.selected_options_without_decorator(champ),
{ selected: champ.selected_options,
disabled: champ.drop_down_list.disabled_options },
multiple: true,
class: 'select2'

View file

@ -1,64 +0,0 @@
require 'rails_helper'
RSpec.describe ChampHelper, type: :helper do
let(:type_de_champ) { create(:type_de_champ) }
let(:champ) { type_de_champ.champ.create }
describe '.formatted_value' do
subject { formatted_value(champ) }
describe 'for a checkbox' do
let(:type_de_champ) { create(:type_de_champ_checkbox) }
context 'when value is on' do
before { champ.update value: 'on' }
it { is_expected.to eq 'Oui' }
end
context 'when value is other' do
it { is_expected.to eq 'Non' }
end
end
describe 'for a engagement' do
let(:type_de_champ) { create(:type_de_champ_engagement) }
context 'when value is on' do
before { champ.update value: 'on' }
it { is_expected.to eq 'Oui' }
end
context 'when value is other' do
it { is_expected.to eq 'Non' }
end
end
describe 'for a multiple_drop_down_list' do
let(:type_de_champ) { create(:type_de_champ_multiple_drop_down_list) }
context 'when value is an array' do
before { champ.update value: '["1", "2"]' }
it { is_expected.to eq '1, 2' }
end
context 'when value is empty' do
before { champ.update value: '' }
it { is_expected.to eq '' }
end
end
describe "for a date" do
let(:type_de_champ) { create(:type_de_champ_date) }
context "when value is an ISO date" do
before { champ.update value: "2017-12-31" }
it { is_expected.to eq "31/12/2017" }
end
context "when value is empty" do
before { champ.update value: nil }
it { is_expected.to eq nil }
end
end
end
end

View file

@ -1,12 +1,19 @@
describe DossierLinkHelper do
describe "#dossier_linked_path" do
context "when no access" do
context "when no access as a gestionnaire" do
let(:gestionnaire) { create(:gestionnaire) }
let(:dossier) { create(:dossier) }
it { expect(helper.dossier_linked_path(gestionnaire, dossier)).to be_nil }
end
context "when no access as a user" do
let(:user) { create(:user) }
let(:dossier) { create(:dossier) }
it { expect(helper.dossier_linked_path(user, dossier)).to be_nil }
end
context "when access as gestionnaire" do
let(:dossier) { create(:dossier) }
let(:gestionnaire) { create(:gestionnaire) }
@ -23,5 +30,14 @@ describe DossierLinkHelper do
it { expect(helper.dossier_linked_path(gestionnaire, dossier)).to eq(gestionnaire_avis_path(avis)) }
end
context "when access as user" do
let(:dossier) { create(:dossier) }
let(:user) { create(:user) }
before { dossier.user = user }
it { expect(helper.dossier_linked_path(user, dossier)).to eq(dossier_path(dossier)) }
end
end
end

View file

@ -104,19 +104,19 @@ describe Champ do
context 'if yes' do
let(:value) { 'true' }
it { expect(champ.for_export).to eq('oui') }
it { expect(champ.for_export).to eq('Oui') }
end
context 'if no' do
let(:value) { 'false' }
it { expect(champ.for_export).to eq('non') }
it { expect(champ.for_export).to eq('Non') }
end
context 'if nil' do
let(:value) { nil }
it { expect(champ.for_export).to eq(nil) }
it { expect(champ.for_export).to eq('Non') }
end
end

View file

@ -9,13 +9,13 @@ describe Champs::CheckboxChamp do
context 'when the value is on' do
let(:value) { 'on' }
it { is_expected.to eq('oui') }
it { is_expected.to eq('Oui') }
end
context 'when the value is off' do
let(:value) { 'off' }
it { is_expected.to eq('non') }
it { is_expected.to eq('Non') }
end
end
end

View file

@ -16,12 +16,12 @@ describe Champs::LinkedDropDownListChamp do
it { expect(champ.value).to eq('["tata","tutu"]') }
end
describe '#for_display' do
describe '#to_s' do
let(:champ) { described_class.new(primary_value: primary_value, secondary_value: secondary_value) }
let(:primary_value) { nil }
let(:secondary_value) { nil }
subject { champ.for_display }
subject { champ.to_s }
context 'with no value' do
it { is_expected.to eq('') }

View file

@ -5,19 +5,19 @@ describe Champs::YesNoChamp do
context 'when the value is false' do
let(:value) { "false" }
it { is_expected.to eq("non") }
it { is_expected.to eq("Non") }
end
context 'when the value is true' do
let(:value) { "true" }
it { is_expected.to eq("oui") }
it { is_expected.to eq("Oui") }
end
context 'when the value is nil' do
let(:value) { nil }
it { is_expected.to eq("non") }
it { is_expected.to eq("Non") }
end
end
end