Skip to content

Commit e11dd70

Browse files
authored
Merge pull request #13451 from demarche-numerique/push-knlxrkqvlvln
Tech: filtrer les valeurs de préremplissage dans les classes PrefillTypeDeChamp
2 parents 3a91125 + 74f2ba6 commit e11dd70

46 files changed

Lines changed: 1199 additions & 311 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/models/champs/civilite_champ.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
class Champs::CiviliteChamp < Champ
4-
validates :value, inclusion: ["M.", "Mme"], allow_nil: true, allow_blank: false, if: :should_validate_in_current_context?
4+
validates :value, inclusion: [Individual::GENDER_MALE, Individual::GENDER_FEMALE], allow_nil: true, allow_blank: false, if: :should_validate_in_current_context?
55

66
def legend_label?
77
true

app/models/champs/date_champ.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Champs::DateChamp < Champ
44
attr_accessor :prefilling_from_france_connect_information
55

66
validates_with DateLimitValidator, if: :should_validate_in_current_context?
7-
before_validation :convert_to_iso8601_date, unless: -> { validation_context == :prefill }
7+
normalizes :value, with: -> { DateDetectionUtils.convert_to_iso8601_date(it) }
88
before_save :clear_prefilled_from_france_connect_information_flag_if_modified
99
validate :iso_8601
1010

@@ -22,10 +22,6 @@ def clear_prefilled_from_france_connect_information_flag_if_modified
2222
data.delete("prefilled_from_france_connect_information")
2323
end
2424

25-
def convert_to_iso8601_date
26-
self.value = DateDetectionUtils.convert_to_iso8601_date(value)
27-
end
28-
2925
def iso_8601
3026
return if DateDetectionUtils.parsable_iso8601_date?(value) || value.blank?
3127

app/models/champs/datetime_champ.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class Champs::DatetimeChamp < Champ
44
validates_with DateLimitValidator, if: :should_validate_in_current_context?
5-
normalizes :value, with: -> v { DateDetectionUtils.convert_to_iso8601_datetime(v) }
5+
normalizes :value, with: -> { DateDetectionUtils.convert_to_iso8601_datetime(it) }
66
validate :iso_8601
77

88
def search_terms
Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,7 @@
11
# frozen_string_literal: true
22

33
class Champs::DecimalNumberChamp < Champ
4+
validates_with NumberFormatValidator, if: :should_validate_in_current_context?
45
validates_with NumberLimitValidator, if: :should_validate_in_current_context?
5-
before_validation :format_value
6-
7-
validates :value, numericality: {
8-
allow_nil: true,
9-
allow_blank: true,
10-
message: -> (object, _data) {
11-
object.errors.generate_message(:value, :not_a_number)
12-
},
13-
}, format: {
14-
with: /\A-?[0-9]+([\.,][0-9]{1,3})?\z/,
15-
allow_nil: true,
16-
allow_blank: true,
17-
message: -> (object, _data) {
18-
# i18n-tasks-use t('errors.messages.not_a_float')
19-
object.errors.generate_message(:value, :not_a_float)
20-
},
21-
}, if: :should_validate_in_current_context?
22-
23-
private
24-
25-
def format_value
26-
return if value.blank?
27-
28-
self.value = value.tr(",", ".").gsub(/[[:space:]]/, "")
29-
end
6+
normalizes :value, with: -> { NumberFormatValidator.normalize(it, decimal: true) }
307
end
Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,5 @@
11
# frozen_string_literal: true
22

33
class Champs::DossierLinkChamp < Champ
4-
validate :value_integerable, if: -> { value.present? }, on: :prefill
5-
validate :dossier_exists, if: -> { should_validate_in_current_context? && value.present? }
6-
validate :dossier_in_allowed_procedures, if: -> { should_validate_in_current_context? && value.present? }
7-
8-
private
9-
10-
def dossier_exists
11-
linked_dossier = Dossier.find_by(id: value)
12-
if linked_dossier.nil? && !DeletedDossier.exists?(dossier_id: value)
13-
errors.add(:value, :not_found)
14-
elsif linked_dossier&.brouillon?
15-
errors.add(:value, :brouillon_not_allowed)
16-
end
17-
end
18-
19-
def dossier_in_allowed_procedures
20-
return if errors.include?(:value) # dossier_exists already failed
21-
return if !type_de_champ.procedures_limit?
22-
23-
allowed_ids = type_de_champ.dossier_link_procedure_ids
24-
return if allowed_ids.empty?
25-
26-
dossier_matches = Dossier.joins(:revision).exists?(id: value, user: dossier.user, procedure_revisions: { procedure_id: allowed_ids })
27-
deleted_dossier_matches = DeletedDossier.exists?(dossier_id: value, user_id: dossier.user_id, procedure_id: allowed_ids)
28-
29-
if !dossier_matches && !deleted_dossier_matches
30-
errors.add(:value, :not_in_allowed_procedures)
31-
end
32-
end
33-
34-
def value_integerable
35-
Integer(value)
36-
rescue ArgumentError
37-
errors.add(:value, :not_integerable)
38-
end
4+
validates_with DossierLinkValidator, if: -> { should_validate_in_current_context? && value.present? }
395
end
Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,7 @@
11
# frozen_string_literal: true
22

33
class Champs::IntegerNumberChamp < Champ
4+
validates_with NumberFormatValidator, if: :should_validate_in_current_context?
45
validates_with NumberLimitValidator, if: :should_validate_in_current_context?
5-
before_validation :format_value
6-
7-
validates :value, numericality: {
8-
only_integer: true,
9-
allow_nil: true,
10-
allow_blank: true,
11-
message: -> (object, _data) {
12-
# i18n-tasks-use t('errors.messages.not_an_integer')
13-
object.errors.generate_message(:value, :not_an_integer)
14-
},
15-
}, if: :should_validate_in_current_context?
16-
17-
def format_value
18-
return if value.blank?
19-
20-
self.value = value.gsub(/[[:space:]]/, "")
21-
end
6+
normalizes :value, with: -> { NumberFormatValidator.normalize(it) }
227
end

app/models/champs/multiple_drop_down_list_champ.rb

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class Champs::MultipleDropDownListChamp < Champ
44
store_accessor :value_json, :referentiels
5-
validate :values_are_in_options, if: -> { value.present? && should_validate_in_current_context? }
5+
validates_with DropDownOptionsValidator, if: -> { value.present? && should_validate_in_current_context? }
66
before_save :store_referentiels, if: :drop_down_advanced?
77

88
THRESHOLD_NB_OPTIONS_AS_CHECKBOX = 5
@@ -43,17 +43,24 @@ def checkbox_label_id(value)
4343
"#{checkbox_id(value)}-label"
4444
end
4545

46-
def value=(value)
47-
return super(nil) if value.blank?
48-
46+
# Parses a raw input (array, JSON string or scalar) into the list of
47+
# selected options; shared with the prefill screening so both sides agree
48+
# on what a raw value selects.
49+
def self.parse_values(value, existing = [])
4950
values = if value.is_a?(Array)
5051
value
51-
elsif value.starts_with?('[')
52-
JSON.parse(value) rescue selected_options + [value] # value may start by [ without being a real JSON value
52+
elsif value.is_a?(String) && value.starts_with?('[')
53+
JSON.parse(value) rescue existing + [value] # value may start by [ without being a real JSON value
5354
else
54-
selected_options + [value]
55-
end.uniq.without('')
55+
existing + [value]
56+
end
57+
values.uniq.without('')
58+
end
5659

60+
def value=(value)
61+
return super(nil) if value.blank?
62+
63+
values = self.class.parse_values(value, selected_options)
5764
if values.empty?
5865
super(nil)
5966
else
@@ -106,13 +113,4 @@ def referentiels_from(value)
106113
rescue JSON::ParserError
107114
{}
108115
end
109-
110-
def values_are_in_options
111-
json = selected_options.compact_blank
112-
return if json.empty?
113-
return if (json - drop_down_options).empty? && !drop_down_advanced?
114-
return if drop_down_advanced? && referentiels.present? && (json - referentiels.keys).empty?
115-
116-
errors.add(:value, :not_in_options)
117-
end
118116
end

app/models/champs/pays_champ.rb

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ class Champs::PaysChamp < Champs::TextChamp
66
validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: true, allow_blank: false
77
end
88

9-
# def value=(code) can reset champs to nil if value is empty, in case of prefill
10-
# we do not want to try to save the champ with an nil value
11-
with_options if: -> { validation_context == :prefill } do
12-
validates :external_id, inclusion: APIGeoService.countries.pluck(:code), allow_nil: false, allow_blank: false
13-
validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: false, allow_blank: false
14-
end
15-
169
def selected
1710
code || value
1811
end

app/models/concerns/champ_validate_concern.rb

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,7 @@ module ChampValidateConcern
1010
private
1111

1212
def should_validate_in_current_context?
13-
case validation_context
14-
when :champ_value
15-
visible?
16-
when :prefill
17-
true
18-
else
19-
false
20-
end
13+
validation_context == :champ_value && visible?
2114
end
2215

2316
def validate_external_data_response?

app/models/prefill_champs.rb

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,6 @@ def build_prefill_values
3131
end
3232

3333
class PrefillValue
34-
NEED_VALIDATION_TYPES_DE_CHAMPS = [
35-
TypeDeChamp.type_champs.fetch(:decimal_number),
36-
TypeDeChamp.type_champs.fetch(:integer_number),
37-
TypeDeChamp.type_champs.fetch(:date),
38-
TypeDeChamp.type_champs.fetch(:datetime),
39-
TypeDeChamp.type_champs.fetch(:civilite),
40-
TypeDeChamp.type_champs.fetch(:yes_no),
41-
TypeDeChamp.type_champs.fetch(:checkbox),
42-
TypeDeChamp.type_champs.fetch(:pays),
43-
TypeDeChamp.type_champs.fetch(:regions),
44-
TypeDeChamp.type_champs.fetch(:departements),
45-
TypeDeChamp.type_champs.fetch(:multiple_drop_down_list),
46-
TypeDeChamp.type_champs.fetch(:epci),
47-
TypeDeChamp.type_champs.fetch(:dossier_link),
48-
]
49-
5034
attr_reader :champ, :value, :dossier
5135

5236
def initialize(champ:, value:, dossier:)
@@ -56,7 +40,7 @@ def initialize(champ:, value:, dossier:)
5640
end
5741

5842
def prefillable?
59-
champ.prefillable? && champ_attributes.present? && valid?
43+
champ.prefillable? && champ_attributes.present?
6044
end
6145

6246
# An array of [champ, attributes] pairs; a repetition champ expands to
@@ -70,14 +54,5 @@ def champ_attributes
7054
.build(champ.type_de_champ, dossier.revision)
7155
.to_assignable_attributes(champ, value)
7256
end
73-
74-
private
75-
76-
def valid?
77-
return true unless NEED_VALIDATION_TYPES_DE_CHAMPS.include?(champ.type_champ)
78-
79-
champ.assign_attributes(champ_attributes)
80-
champ.valid?(:prefill)
81-
end
8257
end
8358
end

0 commit comments

Comments
 (0)