Merge branch 'dev'

This commit is contained in:
gregoirenovel 2018-09-13 10:31:39 +02:00
commit 400afa6ff7
20 changed files with 220 additions and 90 deletions

View file

@ -83,6 +83,20 @@ form {
overflow: hidden; overflow: hidden;
} }
// Mobile Safari doesn't bubble mouse events by default, unless:
//
// - the target element of the event is a link or a form field.
// - the target element, or any of its ancestors up to but not including the <body>, has an explicit event handler set for any of the mouse events. This event handler may be an empty function.
// - the target element, or any of its ancestors up to and including the document has a cursor: pointer CSS declarations.
//
// (See https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html)
//
// This is a problem for us, because we bind a lot of click events as
// `document.on('click', '.my-element', )` which requires proper bubbling.
.ios #wrap {
cursor: pointer;
}
#wrap::after { #wrap::after {
content: ""; content: "";
display: block; display: block;

View file

@ -18,6 +18,20 @@ select {
min-height: 100%; min-height: 100%;
} }
// Mobile Safari doesn't bubble mouse events by default, unless:
//
// - the target element of the event is a link or a form field.
// - the target element, or any of its ancestors up to but not including the <body>, has an explicit event handler set for any of the mouse events. This event handler may be an empty function.
// - the target element, or any of its ancestors up to and including the document has a cursor: pointer CSS declarations.
//
// (See https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html)
//
// This is a problem for us, because we bind a lot of click events as
// `document.on('click', '.my-element', )` which requires proper bubbling.
.ios .page-wrapper {
cursor: pointer;
}
h1 { h1 {
font-size: 36px; font-size: 36px;
font-weight: bold; font-weight: bold;

View file

@ -12,7 +12,6 @@
} }
.right-spinner { .right-spinner {
display: none;
position: absolute; position: absolute;
top: 3.7em; top: 3.7em;
right: 1.2em; right: 1.2em;

View file

@ -1,31 +1,51 @@
class Champs::SiretController < ApplicationController class Champs::SiretController < ApplicationController
def index before_action :authenticate_logged_user!
siret, champ_id = params.required([:siret, :champ_id])
@champ = Champs::SiretChamp.find(champ_id) def show
@etablissement = @champ.etablissement @position = params[:position]
if siret == 'blank' extract_siret
if @etablissement find_etablisement
@etablissement.mark_for_destruction
end if @siret.empty?
@blank = true @etablissement&.mark_for_destruction
elsif siret == 'invalid' elsif @siret.present? && @siret.length == 14
if @etablissement etablissement = find_etablisement_with_siret
@etablissement.mark_for_destruction if etablissement.present?
end @etablissement = etablissement
@error = "Le numéro de SIRET doit comporter exactement 14 chiffres."
else
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(siret, @champ.dossier.procedure_id)
if etablissement_attributes.present?
@etablissement = @champ.build_etablissement(etablissement_attributes)
@etablissement.champ = @champ
else else
message = ['Nous navons pas trouvé détablissement correspondant à ce numéro de SIRET.'] @etablissement&.mark_for_destruction
message << helpers.link_to('Plus dinformations', "https://faq.demarches-simplifiees.fr/article/4-erreur-siret", target: '_blank') @siret = :not_found
@error = helpers.safe_join(message, ' ')
end end
else
@etablissement&.mark_for_destruction
@siret = :invalid
end end
respond_to do |format| end
format.js
private
def extract_siret
if params[:dossier].key?(:champs_attributes)
@siret = params[:dossier][:champs_attributes][@position][:value]
@attribute = "dossier[champs_attributes][#{@position}][etablissement_attributes]"
else
@siret = params[:dossier][:champs_private_attributes][@position][:value]
@attribute = "dossier[champs_private_attributes][#{@position}][etablissement_attributes]"
end
end
def find_etablisement
if params[:champ_id].present?
champ = Champ.find_by(dossier_id: logged_user.dossiers, id: params[:champ_id])
@etablissement = champ&.etablissement
end
@procedure_id = champ&.dossier&.procedure_id || 'aperçu'
end
def find_etablisement_with_siret
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(@siret, @procedure_id)
if etablissement_attributes.present?
Etablissement.new(etablissement_attributes)
end end
end end
end end

View file

@ -221,19 +221,19 @@ module NewGestionnaire
current_filters.map do |filter| current_filters.map do |filter|
case filter['table'] case filter['table']
when 'self' when 'self'
dossiers.where("? LIKE ?", filter['column'], "%#{filter['value']}%") dossiers.where("? ILIKE ?", filter['column'], "%#{filter['value']}%")
when 'france_connect_information' when 'france_connect_information'
dossiers dossiers
.includes(user: :france_connect_information) .includes(user: :france_connect_information)
.where("? LIKE ?", "france_connect_informations.#{filter['column']}", "%#{filter['value']}%") .where("? ILIKE ?", "france_connect_informations.#{filter['column']}", "%#{filter['value']}%")
when 'type_de_champ', 'type_de_champ_private' when 'type_de_champ', 'type_de_champ_private'
relation = filter['table'] == 'type_de_champ' ? :champs : :champs_private relation = filter['table'] == 'type_de_champ' ? :champs : :champs_private
dossiers dossiers
.includes(relation) .includes(relation)
.where("champs.type_de_champ_id = ?", filter['column'].to_i) .where("champs.type_de_champ_id = ?", filter['column'].to_i)
.where("champs.value LIKE ?", "%#{filter['value']}%") .where("champs.value ILIKE ?", "%#{filter['value']}%")
when 'entreprise' when 'entreprise'
table = 'etablissement' table = 'etablissement'
if filter['column'] == 'date_creation' if filter['column'] == 'date_creation'
@ -244,12 +244,12 @@ module NewGestionnaire
else else
dossiers dossiers
.includes(table) .includes(table)
.where("#{table.pluralize}.entreprise_#{filter['column']} LIKE ?", "%#{filter['value']}%") .where("#{table.pluralize}.entreprise_#{filter['column']} ILIKE ?", "%#{filter['value']}%")
end end
when 'user', 'etablissement' when 'user', 'etablissement'
dossiers dossiers
.includes(filter['table']) .includes(filter['table'])
.where("#{filter['table'].pluralize}.#{filter['column']} LIKE ?", "%#{filter['value']}%") .where("#{filter['table'].pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%")
end.pluck(:id) end.pluck(:id)
end.reduce(:&) end.reduce(:&)
end end

View file

@ -1,35 +0,0 @@
import $ from 'jquery';
$(document).on('input', '[data-siret]', evt => {
const input = $(evt.target);
const value = input.val();
const url = input.data('siret');
switch (value.length) {
case 0:
input.removeData('invalid');
$.get(url, { siret: 'blank' });
break;
case 14:
input.attr('disabled', true);
$('.spinner').show();
$.get(url, { siret: value }).then(
() => {
input.removeData('invalid');
input.removeAttr('disabled');
$('.spinner').hide();
},
() => {
input.removeAttr('disabled');
input.data('invalid', true);
$('.spinner').hide();
}
);
break;
default:
if (!input.data('invalid')) {
input.data('invalid', true);
$.get(url, { siret: 'invalid' });
}
}
});

View file

@ -0,0 +1,16 @@
import Rails from 'rails-ujs';
import { show, hide } from '../shared/utils';
const { delegate } = Rails;
function showSpinner() {
[...document.querySelectorAll('.spinner')].forEach(show);
}
function hideSpinner() {
[...document.querySelectorAll('.spinner')].forEach(hide);
}
delegate(document, '[data-spinner]', 'ajax:complete', hideSpinner);
delegate(document, '[data-spinner]', 'ajax:stopped', hideSpinner);
delegate(document, '[data-spinner]', 'ajax:send', showSpinner);

View file

@ -12,13 +12,13 @@ import '../shared/safari-11-file-xhr-workaround';
import '../shared/autocomplete'; import '../shared/autocomplete';
import '../shared/remote-input'; import '../shared/remote-input';
import '../new_design/spinner';
import '../new_design/buttons'; import '../new_design/buttons';
import '../new_design/form-validation'; import '../new_design/form-validation';
import '../new_design/carto'; import '../new_design/carto';
import '../new_design/select2'; import '../new_design/select2';
import '../new_design/champs/linked-drop-down-list'; import '../new_design/champs/linked-drop-down-list';
import '../new_design/champs/siret';
import { toggleCondidentielExplanation } from '../new_design/avis'; import { toggleCondidentielExplanation } from '../new_design/avis';
import { togglePrintMenu } from '../new_design/dossier'; import { togglePrintMenu } from '../new_design/dossier';

View file

@ -0,0 +1,11 @@
export function show({ classList }) {
classList.remove('hidden');
}
export function hide({ classList }) {
classList.add('hidden');
}
export function toggle({ classList }) {
classList.toggle('hidden');
}

View file

@ -1,5 +0,0 @@
<% if @blank || @error %>
<%= render_to_element("#etablissement-for-#{@champ.id}", partial: 'shared/champs/siret/delete_etablissement', locals: { message: @error, position: @champ.order_place, etablissement: @etablissement }) %>
<% else %>
<%= render_to_element("#etablissement-for-#{@champ.id}", partial: 'shared/champs/siret/etablissement', locals: { position: @champ.order_place, etablissement: @etablissement }) %>
<% end %>

View file

@ -0,0 +1,6 @@
<%= render_to_element(".siret-info-#{@position}",
partial: 'shared/champs/siret/etablissement',
locals: {
siret: @siret,
attribute: @attribute,
etablissement: @etablissement }) %>

View file

@ -67,7 +67,7 @@
required: true required: true
= label_tag :nb_of_dossiers do = label_tag :nb_of_dossiers do
Nombre de dossiers usagers qui seront démateerialisés, par an ? (Mettez 0 si vous ne savez pas) Nombre de dossiers usagers qui seront dématérialisés, par an ? (Mettez 0 si vous ne savez pas)
%span.mandatory * %span.mandatory *
= number_field_tag :nb_of_dossiers, nil, required: true = number_field_tag :nb_of_dossiers, nil, required: true

View file

@ -20,7 +20,7 @@
DATA = [{ DATA = [{
sentry: #{raw(sentry_config)} sentry: #{raw(sentry_config)}
}]; }];
%body %body{ class: browser.platform.ios? ? 'ios' : nil }
= render partial: 'layouts/outdated_browser_banner' = render partial: 'layouts/outdated_browser_banner'
= render partial: 'layouts/pre_maintenance' = render partial: 'layouts/pre_maintenance'
- if staging? - if staging?

View file

@ -25,7 +25,7 @@
DATA = [{ DATA = [{
sentry: #{raw(sentry_config)} sentry: #{raw(sentry_config)}
}]; }];
%body %body{ class: browser.platform.ios? ? 'ios' : nil }
.page-wrapper .page-wrapper
= render partial: "layouts/outdated_browser_banner" = render partial: "layouts/outdated_browser_banner"
= render partial: 'layouts/pre_maintenance' = render partial: 'layouts/pre_maintenance'

View file

@ -1,5 +0,0 @@
.mandatory= message
- if etablissement.present?
- champ_attributes = etablissement.champ.private? ? 'champs_private_attributes' : 'champs_attributes'
= fields_for "dossier[#{champ_attributes}][#{position}][etablissement_attributes]", etablissement do |form|
= form.hidden_field :_destroy

View file

@ -1,4 +1,17 @@
= render partial: 'shared/dossiers/editable_champs/etablissement_titre', locals: { etablissement: etablissement } - case siret
- champ_attributes = etablissement.champ.private? ? 'champs_private_attributes' : 'champs_attributes' - when :invalid
= fields_for "dossier[#{champ_attributes}][#{position}][etablissement_attributes]", etablissement do |form| Le numéro de SIRET doit comporter exactement 14 chiffres.
= render partial: 'shared/dossiers/editable_champs/etablissement', locals: { form: form, signature: etablissement.sign }
- when :not_found
Nous navons pas trouvé détablissement correspondant à ce numéro de SIRET.
= link_to('Plus dinformations', "https://faq.demarches-simplifiees.fr/article/4-erreur-siret", target: '_blank')
- else
- if siret.present? && siret == etablissement&.siret
= render partial: 'shared/dossiers/editable_champs/etablissement_titre', locals: { etablissement: etablissement }
= fields_for attribute, etablissement do |form|
= render partial: 'shared/dossiers/editable_champs/etablissement', locals: { form: form, signature: etablissement.sign }
- elsif etablissement.present?
= fields_for attribute, etablissement do |form|
= form.hidden_field :_destroy

View file

@ -1,11 +1,11 @@
= form.text_field :value, = form.text_field :value,
placeholder: champ.libelle, placeholder: champ.libelle,
class: 'small-margin', class: 'small-margin',
data: { siret: champ.persisted? ? champs_siret_path(format: :js, champ_id: champ) : nil }, data: { remote: true, debounce: true, url: champs_siret_path(form.index), params: { champ_id: champ&.id }.to_query, spinner: true },
required: champ.mandatory? required: champ.mandatory?
.spinner.right-spinner .spinner.right-spinner.hidden
%div{ id: "etablissement-for-#{champ.id}" } %div{ class: "siret-info-#{form.index}" }
- if champ.etablissement.present? - if champ.etablissement.present?
= render partial: 'shared/dossiers/editable_champs/etablissement_titre', locals: { etablissement: champ.etablissement } = render partial: 'shared/dossiers/editable_champs/etablissement_titre', locals: { etablissement: champ.etablissement }
= form.fields_for :etablissement do |form| = form.fields_for :etablissement do |form|
= render partial: 'shared/dossiers/editable_champs/etablissement', locals: { form: form, signature: champ.etablissement.sign } = render partial: 'shared/dossiers/editable_champs/etablissement', locals: { form: form, signature: champ.etablissement.sign }

View file

@ -110,7 +110,7 @@ Rails.application.routes.draw do
end end
namespace :champs do namespace :champs do
get ':champ_id/siret' => 'siret#index', as: 'siret' get ':position/siret', to: 'siret#show', as: :siret
get ':position/dossier_link', to: 'dossier_link#show', as: :dossier_link get ':position/dossier_link', to: 'dossier_link#show', as: :dossier_link
end end

View file

@ -1,5 +1,5 @@
namespace :'2018_09_12_ftap' do namespace :'2018_09_12_ftap' do
task :run do task run: :environment do
procedure = Procedure.find(5812) procedure = Procedure.find(5812)
dossiers = procedure.dossiers.all dossiers = procedure.dossiers.all

View file

@ -0,0 +1,82 @@
require 'spec_helper'
describe Champs::SiretController, type: :controller do
let(:user) { create(:user) }
let(:procedure) { create(:procedure, :published) }
describe '#show' do
let(:dossier) { create(:dossier, user: user, procedure: procedure) }
let(:params) do
{
dossier: {
champs_attributes: {
'1' => { value: "#{siret}" }
}
},
position: '1'
}
end
let(:siret) { '' }
context 'when user is connected' do
render_views
before { sign_in user }
context 'when siret empty' do
before {
get :show, params: params, format: 'js'
}
it 'empty info message' do
expect(response.body).to include('.siret-info-1')
expect(response.body).to include('innerHTML = ""')
end
end
context 'when siret invalid' do
let(:siret) { '1234' }
before {
get :show, params: params, format: 'js'
}
it 'invalid error' do
expect(response.body).to include('Le numéro de SIRET doit comporter exactement 14 chiffres.')
end
end
context 'when siret not found' do
let(:siret) { '0' * 14 }
before {
expect(subject).to receive(:find_etablisement_with_siret).and_return(false)
get :show, params: params, format: 'js'
}
it 'not found error' do
expect(response.body).to include('Nous navons pas trouvé détablissement correspondant à ce numéro de SIRET.')
end
end
context 'when siret found' do
let(:siret) { etablissement.siret }
let(:etablissement) { build(:etablissement) }
before {
expect(subject).to receive(:find_etablisement_with_siret).and_return(etablissement)
get :show, params: params, format: 'js'
}
it 'etablissement info message' do
expect(response.body).to include(etablissement.entreprise_raison_sociale)
expect(response.body).to include(etablissement.entreprise_capital_social.to_s)
end
end
end
context 'when user is not connected' do
before {
get :show, params: { position: '1' }, format: 'js'
}
it { expect(response.code).to eq('401') }
end
end
end