From d4bbcdf6823cb3fed53ca4cf4c21153b6303f1a2 Mon Sep 17 00:00:00 2001 From: Simon Lehericey Date: Thu, 27 Jul 2017 20:54:02 +0200 Subject: [PATCH] Champ: add before save logic to serialize datetime and dropdownlist fields --- app/models/champ.rb | 29 +++++++++++++++++++ spec/models/champ_spec.rb | 59 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/app/models/champ.rb b/app/models/champ.rb index 58ad82378..e509751c7 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -6,6 +6,9 @@ class Champ < ActiveRecord::Base delegate :libelle, :type_champ, :order_place, :mandatory, :description, :drop_down_list, to: :type_de_champ before_save :format_date_to_iso, if: Proc.new { type_champ == 'date' } + before_save :serialize_datetime_if_needed, if: Proc.new { type_champ == 'datetime' } + before_save :multiple_select_to_string, if: Proc.new { type_champ == 'multiple_drop_down_list' } + after_save :internal_notification, if: Proc.new { !dossier.nil? } def mandatory? @@ -65,9 +68,35 @@ class Champ < ActiveRecord::Base self.value = date end + def serialize_datetime_if_needed + if (value =~ /=>/).present? + date = begin + hash_date = YAML.safe_load(value.gsub('=>', ': ')) + year, month, day, hour, minute = hash_date.values_at(1,2,3,4,5) + DateTime.new(year, month, day, hour, minute).strftime("%d/%m/%Y %H:%M") + rescue + nil + end + + self.value = date + end + end + def internal_notification unless dossier.state == 'draft' NotificationService.new('champs', self.dossier.id, self.libelle).notify end end + + def multiple_select_to_string + if value.present? + json = JSON.parse(value) + if json == [''] + self.value = nil + else + json = json - [''] + self.value = json.to_s + end + end + end end diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index 868001afc..4769a6e7f 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -4,4 +4,63 @@ describe Champ do require 'models/champ_shared_example.rb' it_should_behave_like "champ_spec" + + describe '#serialize_datetime_if_needed' do + let(:type_de_champ) { TypeDeChamp.new(type_champ: 'datetime') } + let(:champ) { Champ.new(type_de_champ: type_de_champ, value: value) } + + before { champ.save } + + # when using the old form, and the ChampsService Class + # TODO: to remove + context 'when the value is already serialized' do + let(:value) { '12/01/2017 10:23' } + + it { expect(champ.value).to eq(value) } + end + + context 'when the value is not already serialized' do + let(:value) { '{ 1=>2017, 2=>01, 3=>12, 4=>10, 5=>23 }' } + + it { expect(champ.value).to eq('12/01/2017 10:23') } + end + end + + describe '#multiple_select_to_string' do + let(:type_de_champ) { TypeDeChamp.new(type_champ: 'multiple_drop_down_list') } + let(:champ) { Champ.new(type_de_champ: type_de_champ, value: value) } + + before { champ.save } + + # when using the old form, and the ChampsService Class + # TODO: to remove + context 'when the value is already deserialized' do + let(:value) { '["1", "2"]' } + + it { expect(champ.value).to eq(value) } + + context 'when the value is nil' do + let(:value) { nil } + + it { expect(champ.value).to eq(value) } + end + end + + # for explanation for the "" entry, see + # https://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select + # GOTCHA + context 'when the value is not already deserialized' do + context 'when a choice is selected' do + let(:value) { '["", "1", "2"]' } + + it { expect(champ.value).to eq('["1", "2"]') } + end + + context 'when all choices are removed' do + let(:value) { '[""]' } + + it { expect(champ.value).to eq(nil) } + end + end + end end