commit
3cff988bf3
17 changed files with 95 additions and 67 deletions
2
Gemfile
2
Gemfile
|
@ -64,8 +64,6 @@ gem 'leaflet-rails'
|
|||
gem 'leaflet-markercluster-rails', '~> 0.7.0'
|
||||
gem 'leaflet-draw-rails'
|
||||
|
||||
gem 'bootstrap-datepicker-rails'
|
||||
|
||||
gem 'chartkick'
|
||||
|
||||
gem 'logstasher'
|
||||
|
|
|
@ -93,8 +93,6 @@ GEM
|
|||
bcrypt (3.1.11)
|
||||
bindata (2.4.1)
|
||||
bindex (0.5.0)
|
||||
bootstrap-datepicker-rails (1.6.4.1)
|
||||
railties (>= 3.0)
|
||||
bootstrap-sass (3.3.7)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
sass (>= 3.3.4)
|
||||
|
@ -753,7 +751,6 @@ DEPENDENCIES
|
|||
active_model_serializers
|
||||
administrate
|
||||
apipie-rails
|
||||
bootstrap-datepicker-rails
|
||||
bootstrap-sass (~> 3.3.5)
|
||||
bootstrap-wysihtml5-rails (~> 0.3.3.8)
|
||||
brakeman
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
//= require chartkick
|
||||
//= require_tree ./old_design
|
||||
//= require bootstrap-sprockets
|
||||
//= require bootstrap-datepicker/core
|
||||
//= require bootstrap-datepicker/locales/bootstrap-datepicker.fr.js
|
||||
|
||||
//= require leaflet.js
|
||||
//= require d3.min
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
// = require attestation_recapitulatif
|
||||
|
||||
// = require_self
|
||||
// = require bootstrap-datepicker3
|
||||
// = require leaflet
|
||||
// = require font-awesome
|
||||
// = require franceconnect
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@import "bootstrap";
|
||||
@import "bootstrap-datepicker3";
|
||||
|
||||
#description-page #liste-champs {
|
||||
|
||||
|
|
|
@ -19,6 +19,16 @@ class ChampDecorator < Draper::Decorator
|
|||
end
|
||||
end
|
||||
|
||||
def date_for_input
|
||||
if object.value.present?
|
||||
if type_champ == "date"
|
||||
object.value
|
||||
elsif type_champ == "datetime" && object.value != ' 00:00'
|
||||
DateTime.parse(object.value, "%Y-%m-%d %H:%M").strftime("%Y-%m-%d")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def description_with_links
|
||||
description.gsub(URI.regexp, '<a target="_blank" href="\0">\0</a>') if description
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ 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 :format_datetime, 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.present? }
|
||||
|
@ -17,15 +17,6 @@ class Champ < ActiveRecord::Base
|
|||
mandatory
|
||||
end
|
||||
|
||||
def data_provide
|
||||
return 'datepicker' if (type_champ == 'datetime') && !(BROWSER.value.chrome? || BROWSER.value.edge?)
|
||||
return 'typeahead' if type_champ == 'address'
|
||||
end
|
||||
|
||||
def data_date_format
|
||||
('dd/mm/yyyy' if type_champ == 'datetime')
|
||||
end
|
||||
|
||||
def same_hour? num
|
||||
same_date? num, '%H'
|
||||
end
|
||||
|
@ -102,7 +93,7 @@ class Champ < ActiveRecord::Base
|
|||
self.value = date
|
||||
end
|
||||
|
||||
def serialize_datetime_if_needed
|
||||
def format_datetime
|
||||
if (value =~ /=>/).present?
|
||||
date = begin
|
||||
hash_date = YAML.safe_load(value.gsub('=>', ': '))
|
||||
|
@ -111,8 +102,11 @@ class Champ < ActiveRecord::Base
|
|||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
self.value = date
|
||||
elsif /^\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}$/ =~ value # old browsers can send with dd/mm/yyyy hh:mm format
|
||||
self.value = DateTime.parse(value, "%d/%m/%Y %H:%M").strftime("%Y-%m-%d %H:%M")
|
||||
elsif !(/^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}$/ =~ value) # a datetime not correctly formatted should not be stored
|
||||
self.value = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%input.form-control{ name: "champs['#{champ.id}']",
|
||||
placeholder: "JJ/MM/AAAA",
|
||||
id: "champs_#{champ.id}",
|
||||
value: champ.value ? champ.object.value : champ.value,
|
||||
value: champ.date_for_input,
|
||||
type: "date" }
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
%input.form-control{ name: "champs['#{champ.id}']",
|
||||
placeholder: champ.libelle,
|
||||
id: "champs_#{champ.id}",
|
||||
value: (champ.value.split(/[ ][0-9]*:[0-9]*/).first if champ.value.present?),
|
||||
type: champ.type_champ,
|
||||
'data-provide' => champ.data_provide,
|
||||
'data-date-format' => champ.data_date_format }
|
||||
= render partial: 'users/description/champs/date', locals: { champ: champ }
|
||||
|
||||
%select.form-control{ name: "time_hour['#{champ.id}']", style: 'margin-left: 5px;', id: "time_hour_#{champ.id}" }
|
||||
%br
|
||||
%select.form-control{ name: "time_hour['#{champ.id}']", style: 'width:70px;display:inline;', id: "time_hour_#{champ.id}" }
|
||||
- (0..23).each do |num|
|
||||
- num = "%.2i" %num
|
||||
%option{ value: num, selected: (:selected if champ.same_hour?(num)) }
|
||||
= num
|
||||
h
|
||||
%select.form-control{ name: "time_minute['#{champ.id}']", id: "time_minute_#{champ.id}" }
|
||||
%select.form-control{ name: "time_minute['#{champ.id}']", style: 'width:70px;display:inline;', id: "time_minute_#{champ.id}" }
|
||||
- (0..59).each do |num|
|
||||
- num = "%.2i" %num
|
||||
- if num.to_i%5 == 0
|
||||
|
|
30
lib/tasks/2018_01_18_clean_datetime_in_champs.rake
Normal file
30
lib/tasks/2018_01_18_clean_datetime_in_champs.rake
Normal file
|
@ -0,0 +1,30 @@
|
|||
namespace :'2018_01_18_clean_datetime_in_champs' do
|
||||
task clean: :environment do
|
||||
datetime_champs = TypeDeChamp.where(type_champ: "datetime").flat_map{ |t| t.champ }
|
||||
|
||||
# Match " HH:MM" => nil a datetime is not valid if not composed by date AND time
|
||||
datetime_champs.select { |c| /^\s\d{2}:\d{2}$/.match(c.value) }.each do |c|
|
||||
puts "cleaning #{c.value} => nil"
|
||||
c.update_columns(value: nil)
|
||||
end
|
||||
|
||||
# Match "dd/mm/YYYY HH:MM" => "YYYY-mm-dd HH:MM"
|
||||
datetime_champs.select { |c| /^\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}$/ =~ c.value }.each do |c|
|
||||
formated_date = DateTime.parse(c.value, "%d/%m/%Y %H:%M").strftime("%Y-%m-%d %H:%M")
|
||||
puts "cleaning #{c.value} => #{formated_date}"
|
||||
c.update_columns(value: formated_date)
|
||||
end
|
||||
|
||||
# Match "ddmmYYYY HH:MM" => "YYYY-mm-dd HH:MM"
|
||||
datetime_champs.select { |c| /^\d{8}\s\d{2}:\d{2}$/ =~ c.value }.each do |c|
|
||||
day = c.value[0,2]
|
||||
month = c.value[2,2]
|
||||
year = c.value[4,4]
|
||||
hours = c.value[9,2]
|
||||
minutes = c.value[12,2]
|
||||
formated_date = "#{year}-#{month}-#{day} #{hours}:#{minutes}"
|
||||
puts "cleaning #{c.value} => #{formated_date}"
|
||||
c.update_columns(value: formated_date)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -249,7 +249,7 @@ shared_examples 'description_controller_spec' do
|
|||
describe 'Sauvegarde des champs' do
|
||||
let(:champs_dossier) { dossier.champs }
|
||||
let(:dossier_text_value) { 'test value' }
|
||||
let(:dossier_date_value) { '23/06/2016' }
|
||||
let(:dossier_date_value) { '2018-01-31' }
|
||||
let(:dossier_hour_value) { '17' }
|
||||
let(:dossier_minute_value) { '00' }
|
||||
let(:dossier_datetime_champ_id) { dossier.champs.find { |c| c.type_champ == "datetime" }.id }
|
||||
|
|
|
@ -61,4 +61,36 @@ describe ChampDecorator do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#date_for_input' do
|
||||
subject { decorator.date_for_input }
|
||||
|
||||
describe "for a date" do
|
||||
let(:type_champ) { :date }
|
||||
|
||||
context "when value is an ISO date" do
|
||||
before { champ.update value: "2017-12-31" }
|
||||
it { is_expected.to eq "2017-12-31" }
|
||||
end
|
||||
|
||||
context "when value is empty" do
|
||||
before { champ.update value: nil }
|
||||
it { is_expected.to eq nil }
|
||||
end
|
||||
end
|
||||
|
||||
describe "for a datetime" do
|
||||
let(:type_champ) { :date }
|
||||
|
||||
context "when value is an formatted datetime" do
|
||||
before { champ.update value: "2017-12-30 23:17" }
|
||||
it { is_expected.to eq "2017-12-30" }
|
||||
end
|
||||
|
||||
context "when value is empty" do
|
||||
before { champ.update value: nil }
|
||||
it { is_expected.to eq nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,28 +26,6 @@ shared_examples 'champ_spec' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'data_provide' do
|
||||
let(:champ) { create :champ }
|
||||
|
||||
subject { champ.data_provide }
|
||||
|
||||
context 'when type_champ is datetime' do
|
||||
before do
|
||||
champ.type_de_champ = create :type_de_champ_public, type_champ: 'datetime'
|
||||
end
|
||||
|
||||
it { is_expected.to eq 'datepicker' }
|
||||
end
|
||||
|
||||
context 'when type_champ is address' do
|
||||
before do
|
||||
champ.type_de_champ = create :type_de_champ_public, type_champ: 'address'
|
||||
end
|
||||
|
||||
it { is_expected.to eq 'typeahead' }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.departement', vcr: { cassette_name: 'call_geo_api_departements' } do
|
||||
subject { Champ.departements }
|
||||
|
||||
|
|
|
@ -5,24 +5,22 @@ describe Champ do
|
|||
|
||||
it_should_behave_like "champ_spec"
|
||||
|
||||
describe '#serialize_datetime_if_needed' do
|
||||
describe '#format_datetime' 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' }
|
||||
context 'when the value is sent by a modern browser' do
|
||||
let(:value) { '2017-12-31 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 }' }
|
||||
context 'when the value is sent by a old browser' do
|
||||
let(:value) { '31/12/2018 09:26' }
|
||||
|
||||
it { expect(champ.value).to eq('12/01/2017 10:23') }
|
||||
it { expect(champ.value).to eq('2018-12-31 09:26') }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -179,10 +179,10 @@ describe TagsSubstitutionConcern, type: :model do
|
|||
dossier.champs
|
||||
.select { |champ| champ.type_champ == 'datetime' }
|
||||
.first
|
||||
.update_attributes(value: '13/09/2017 09:00')
|
||||
.update_attributes(value: '2017-09-13 09:00')
|
||||
end
|
||||
|
||||
it { is_expected.to eq('15/04/2017 13/09/2017 09:00') }
|
||||
it { is_expected.to eq('15/04/2017 2017-09-13 09:00') }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ describe ChampsService do
|
|||
end
|
||||
|
||||
it 'parses and save the date' do
|
||||
expect(champ_datetime.value).to eq('d 12:24')
|
||||
expect(champ_datetime.value).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ describe 'users/description/show.html.haml', type: :view do
|
|||
let(:champ_datetime) { champs.where(type_de_champ_id: types_de_champ.id).first }
|
||||
|
||||
before do
|
||||
champ_datetime.value = "22/06/2016 12:05"
|
||||
champ_datetime.value = "2016-06-22 12:05"
|
||||
champ_datetime.save
|
||||
render
|
||||
end
|
||||
|
@ -82,7 +82,7 @@ describe 'users/description/show.html.haml', type: :view do
|
|||
end
|
||||
|
||||
describe 'datetime value is correctly setup when is not nil' do
|
||||
it { expect(rendered).to have_css("input[type='datetime'][id='champs_#{champ_datetime.id}'][value='22/06/2016']") }
|
||||
it { expect(rendered).to have_css("input[type='date'][id='champs_#{champ_datetime.id}'][value='2016-06-22']") }
|
||||
it { expect(rendered).to have_css("option[value='12'][selected='selected']") }
|
||||
it { expect(rendered).to have_css("option[value='05'][selected='selected']") }
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue