Merge branch 'dev'

This commit is contained in:
gregoirenovel 2018-03-23 10:17:16 +01:00
commit da69ff3714
45 changed files with 246 additions and 117 deletions

View file

@ -990,7 +990,7 @@ Style/MethodCalledOnDoEndBlock:
Enabled: false
Style/MethodDefParentheses:
Enabled: false
Enabled: true
Style/MethodMissing:
Enabled: false

View file

@ -457,7 +457,7 @@ GEM
activesupport (>= 4.0)
logstash-event (~> 1.2.0)
request_store
loofah (2.2.0)
loofah (2.2.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lumberjack (1.0.12)

View file

@ -74,7 +74,13 @@ client_id: ''
client_secret: ''
```
*Note : les valeurs pour ces deux paramètres sont renseignées dans le Keepass*
## Connexion a Pipedrive
Dans le fichier `config/intializers/token.rb`, ajouter
`PIPEDRIVE_TOKEN = 'token'`
*Note : les valeurs pour ces paramètres sont renseignées dans le Keepass*
## Création des comptes initiaux

View file

@ -16,7 +16,7 @@
@media (min-width: $two-columns-breakpoint) {
flex-direction: row;
align-items: center;
align-items: stretch;
justify-content: center;
}
}
@ -25,7 +25,6 @@
padding: $two-columns-padding 0 0;
width: 100%;
max-width: 500px;
margin: auto;
@media (min-width: $two-columns-breakpoint) {
padding: $two-columns-padding;

View file

@ -34,7 +34,7 @@ class FranceConnect::ParticulierController < ApplicationController
end
end
def connect_france_connect_particulier user
def connect_france_connect_particulier(user)
sign_out :user if user_signed_in?
sign_out :gestionnaire if gestionnaire_signed_in?
sign_out :administrateur if administrateur_signed_in?

View file

@ -1,16 +1,15 @@
class InvitesController < ApplicationController
before_action :gestionnaire_or_user?
before_action :ensure_user_signed_in
def create
email_sender = @current_devise_profil.email
class_var = @current_devise_profil.class == User ? InviteUser : InviteGestionnaire
dossier = @current_devise_profil.dossiers.find(params[:dossier_id])
email = params[:email].downcase
user = User.find_by(email: email)
invite = class_var.create(dossier: dossier, user: user, email: email, email_sender: email_sender)
invite = InviteUser.create(
dossier: current_user.dossiers.find(params[:dossier_id]),
user: User.find_by(email: email),
email: email,
email_sender: current_user.email
)
if invite.valid?
if invite.user.present?
@ -29,12 +28,9 @@ class InvitesController < ApplicationController
private
def gestionnaire_or_user?
if !user_signed_in? && !gestionnaire_signed_in?
def ensure_user_signed_in
if !user_signed_in?
return redirect_to root_path
end
@current_devise_profil = current_user if user_signed_in?
@current_devise_profil = current_gestionnaire if gestionnaire_signed_in?
end
end

View file

@ -0,0 +1,74 @@
module Manager
class DemandesController < Manager::ApplicationController
PIPEDRIVE_PEOPLE_URL = 'https://api.pipedrive.com/v1/persons'
PIPEDRIVE_POSTE_ATTRIBUTE_ID = '33a790746f1713d712fe97bcce9ac1ca6374a4d6'
PIPEDRIVE_DEV_ID = '2748449'
PIPEDRIVE_CAMILLE_ID = '3189424'
def index
@pending_demandes = pending_demandes
end
def create_administrateur
administrateur = current_administration.invite_admin(create_administrateur_params[:email])
if administrateur.errors.empty?
change_person_owner(create_administrateur_params[:person_id], PIPEDRIVE_CAMILLE_ID)
flash.notice = "Administrateur créé"
redirect_to manager_demandes_path
else
flash.now.alert = administrateur.errors.full_messages
@pending_demandes = pending_demandes
render :index
end
end
private
def change_person_owner(person_id, owner_id)
url = PIPEDRIVE_PEOPLE_URL + "/#{person_id}?api_token=#{PIPEDRIVE_TOKEN}"
params = { 'owner_id': owner_id }
RestClient.put(url, params.to_json, { content_type: :json })
end
def create_administrateur_params
params.require(:administrateur).permit(:email, :person_id)
end
def pending_demandes
already_approved_emails = Administrateur
.where(email: demandes.map { |d| d[:email] })
.pluck(:email)
demandes.reject { |demande| already_approved_emails.include?(demande[:email]) }
end
def demandes
@demandes ||= fetch_demandes
end
def fetch_demandes
params = {
start: 0,
limit: 500,
user_id: PIPEDRIVE_DEV_ID,
api_token: PIPEDRIVE_TOKEN
}
response = RestClient.get(PIPEDRIVE_PEOPLE_URL, { params: params })
json = JSON.parse(response.body)
json['data'].map do |datum|
{
person_id: datum['id'],
nom: datum['name'],
poste: datum[PIPEDRIVE_POSTE_ATTRIBUTE_ID],
email: datum.dig('email', 0, 'value'),
organisation: datum['org_name']
}
end
end
end
end

View file

@ -257,11 +257,11 @@ class Users::DossiersController < UsersController
redirect_to url_for users_dossiers_path
end
def update_current_user_siret! siret
def update_current_user_siret!(siret)
current_user.update(siret: siret)
end
def facade id = params[:id]
def facade(id = params[:id])
DossierFacades.new id, current_user.email
end
end

View file

@ -69,7 +69,7 @@ class Users::RegistrationsController < Devise::RegistrationsController
private
def check_invite! user
def check_invite!(user)
Invite.where(email: user.email).update_all user_id: user.id
end
end

View file

@ -5,7 +5,7 @@ class UsersController < ApplicationController
redirect_to root_path
end
def current_user_dossier dossier_id = nil
def current_user_dossier(dossier_id = nil)
dossier_id ||= params[:dossier_id] || params[:id]
dossier = Dossier.find(dossier_id)
@ -15,7 +15,7 @@ class UsersController < ApplicationController
raise ActiveRecord::RecordNotFound
end
def authorized_routes? controller
def authorized_routes?(controller)
if !UserRoutesAuthorizationService.authorized_route?(controller, current_user_dossier)
redirect_to_root_path 'Le statut de votre dossier n\'autorise pas cette URL'
end
@ -26,7 +26,7 @@ class UsersController < ApplicationController
private
def redirect_to_root_path message
def redirect_to_root_path(message)
flash.alert = message
redirect_to url_for root_path
end

View file

@ -16,7 +16,7 @@ class DossierDecorator < Draper::Decorator
DossierDecorator.case_state_fr state
end
def self.case_state_fr state = self.state
def self.case_state_fr(state = self.state)
h.t("activerecord.attributes.dossier.state.#{state}")
end
end

View file

@ -1,7 +1,7 @@
class TypeDeChampDecorator < Draper::Decorator
delegate_all
def button_up params
def button_up(params)
h.link_to '', params[:url], class: up_classes,
id: "btn_up_#{params[:index]}",
remote: true,
@ -9,7 +9,7 @@ class TypeDeChampDecorator < Draper::Decorator
style: display_up_button?(params[:index], params[:private]) ? '' : 'visibility: hidden;'
end
def button_down params
def button_down(params)
h.link_to '', params[:url], class: down_classes,
id: "btn_down_#{params[:index]}",
remote: true,
@ -39,7 +39,7 @@ class TypeDeChampDecorator < Draper::Decorator
(index + 1) < count_type_de_champ(private)
end
def count_type_de_champ private
def count_type_de_champ(private)
if private
@count_type_de_champ ||= procedure.types_de_champ_private.count
else

View file

@ -1,10 +1,10 @@
class TypeDePieceJustificativeDecorator < Draper::Decorator
delegate_all
def button_up params
def button_up(params)
h.link_to '', params[:url], class: up_classes, id: "btn_up_#{params[:index]}", remote: true, method: :post if display_up_button?(params[:index])
end
def button_down params
def button_down(params)
h.link_to '', params[:url], class: down_classes, id: "btn_down_#{params[:index]}", remote: true, method: :post if display_down_button?(params[:index])
end

View file

@ -1,5 +1,5 @@
class AdminProceduresShowFacades
def initialize procedure
def initialize(procedure)
@procedure = procedure
end

View file

@ -1,7 +1,7 @@
class AdminTypesDeChampFacades
include Rails.application.routes.url_helpers
def initialize private, procedure
def initialize(private, procedure)
@private = private
@procedure = procedure
end
@ -30,15 +30,15 @@ class AdminTypesDeChampFacades
@private ? :types_de_champ_private : :types_de_champ
end
def move_up_url ff
def move_up_url(ff)
@private ? move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_up_admin_procedure_types_de_champ_path(@procedure, ff.index)
end
def move_down_url ff
def move_down_url(ff)
@private ? move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_down_admin_procedure_types_de_champ_path(@procedure, ff.index)
end
def delete_url ff
def delete_url(ff)
@private ? admin_procedure_type_de_champ_private_path(@procedure, ff.object.id) : admin_procedure_type_de_champ_path(@procedure, ff.object.id)
end

View file

@ -1,6 +1,6 @@
class InviteDossierFacades < DossierFacades
# TODO rechercher en fonction de la personne/email
def initialize id, email
def initialize(id, email)
@dossier = Invite.where(email: email, id: id).first!.dossier
end
end

View file

@ -23,7 +23,7 @@ module Carto
private
def self.call api_url
def self.call(api_url)
RestClient.get api_url, params: { fields: :nom }
rescue RestClient::ServiceUnavailable
nil

View file

@ -16,7 +16,7 @@ class CARTO::SGMAP::Cadastre::Adapter
end
end
def filter_properties properties
def filter_properties(properties)
{
surface_intersection: properties[:surface_intersection],
surface_parcelle: properties[:surface_parcelle],

View file

@ -1,7 +1,7 @@
class AdministrationMailer < ApplicationMailer
layout 'mailers/layout'
def new_admin_email admin, administration
def new_admin_email(admin, administration)
@admin = admin
@administration = administration

View file

@ -1,7 +1,7 @@
class GestionnaireMailer < ApplicationMailer
layout 'mailers/layout'
def new_gestionnaire email, password
def new_gestionnaire(email, password)
send_mail email, password, "Vous avez été nommé accompagnateur sur demarches-simplifiees.fr"
end
@ -21,12 +21,12 @@ class GestionnaireMailer < ApplicationMailer
private
def vars_mailer email, args
def vars_mailer(email, args)
@args = args
@email = email
end
def send_mail email, args, subject
def send_mail(email, args, subject)
vars_mailer email, args
mail(to: email, subject: subject)

View file

@ -1,11 +1,11 @@
class InviteMailer < ApplicationMailer
def invite_user invite
def invite_user(invite)
vars_mailer invite
send_mail invite.email, "demarches-simplifiees.fr - Participez à l'élaboration d'un dossier", invite.email_sender if invite.user.present?
end
def invite_guest invite
def invite_guest(invite)
vars_mailer invite
send_mail invite.email, "Invitation - #{invite.email_sender} vous invite à consulter un dossier sur demarches-simplifiees.fr", invite.email_sender
@ -13,11 +13,11 @@ class InviteMailer < ApplicationMailer
private
def vars_mailer invite
def vars_mailer(invite)
@invite = invite
end
def send_mail email, subject, reply_to
def send_mail(email, subject, reply_to)
mail(to: email,
subject: subject,
reply_to: reply_to)

View file

@ -1,5 +1,5 @@
class WelcomeMailer < ApplicationMailer
def welcome_email user
def welcome_email(user)
@user = user
mail(to: user.email,

View file

@ -37,11 +37,11 @@ class Champ < ApplicationRecord
!private?
end
def same_hour? num
def same_hour?(num)
same_date? num, '%H'
end
def same_minute? num
def same_minute?(num)
same_date? num, '%M'
end
@ -53,7 +53,7 @@ class Champ < ApplicationRecord
end
end
def same_date? num, compare
def same_date?(num, compare)
if type_champ == 'datetime' && value.present?
if value.to_datetime.strftime(compare) == num
return true

9
app/models/demande.rb Normal file
View file

@ -0,0 +1,9 @@
class Demande
def self.model_name
self
end
def self.human(*args)
"Demandes"
end
end

View file

@ -193,11 +193,11 @@ class Dossier < ApplicationRecord
en_instruction? || accepte? || refuse? || sans_suite?
end
def owner? email
def owner?(email)
user.email == email
end
def invite_by_user? email
def invite_by_user?(email)
(invites_user.pluck :email).include? email
end

View file

@ -146,7 +146,7 @@ class Gestionnaire < ApplicationRecord
private
def valid_couple_table_attr? table, column
def valid_couple_table_attr?(table, column)
couples = [
{
table: :dossier,

View file

@ -66,19 +66,19 @@ class Procedure < ApplicationRecord
types_de_champ + types_de_champ_private
end
def self.active id
def self.active(id)
publiees.find(id)
end
def switch_types_de_champ index_of_first_element
def switch_types_de_champ(index_of_first_element)
switch_list_order(types_de_champ_ordered, index_of_first_element)
end
def switch_types_de_champ_private index_of_first_element
def switch_types_de_champ_private(index_of_first_element)
switch_list_order(types_de_champ_private_ordered, index_of_first_element)
end
def switch_types_de_piece_justificative index_of_first_element
def switch_types_de_piece_justificative(index_of_first_element)
switch_list_order(types_de_piece_justificative, index_of_first_element)
end

View file

@ -23,7 +23,7 @@ class User < ApplicationRecord
before_validation -> { sanitize_email(:email) }
def self.find_for_france_connect email, siret
def self.find_for_france_connect(email, siret)
user = User.find_by(email: email)
if user.nil?
return User.create(email: email, password: Devise.friendly_token[0, 20], siret: siret)
@ -37,7 +37,7 @@ class User < ApplicationRecord
loged_in_with_france_connect.present?
end
def invite? dossier_id
def invite?(dossier_id)
invites.pluck(:dossier_id).include?(dossier_id.to_i)
end
end

View file

@ -1,5 +1,5 @@
class ClamavService
def self.safe_file? file_path
def self.safe_file?(file_path)
if Rails.env == 'development'
return CLAMAV[:response] if CLAMAV[:mock?]
end

View file

@ -1,5 +1,5 @@
class GeojsonService
def self.to_json_polygon_for_qp coordinates
def self.to_json_polygon_for_qp(coordinates)
polygon = {
geo: {
type: "Polygon",
@ -10,7 +10,7 @@ class GeojsonService
polygon.to_json
end
def self.to_json_polygon_for_cadastre coordinates
def self.to_json_polygon_for_cadastre(coordinates)
polygon = {
geom: {
type: "Feature",

View file

@ -1,5 +1,5 @@
class ModuleApiCartoService
def self.save_qp! dossier, json_latlngs
def self.save_qp!(dossier, json_latlngs)
if dossier.procedure.module_api_carto.quartiers_prioritaires?
qp_list = generate_qp JSON.parse(json_latlngs)
@ -11,7 +11,7 @@ class ModuleApiCartoService
end
end
def self.save_cadastre! dossier, json_latlngs
def self.save_cadastre!(dossier, json_latlngs)
if dossier.procedure.module_api_carto.cadastre?
cadastre_list = generate_cadastre JSON.parse(json_latlngs)
@ -23,7 +23,7 @@ class ModuleApiCartoService
end
end
def self.generate_qp coordinates
def self.generate_qp(coordinates)
coordinates.inject({}) { |acc, coordinate|
acc.merge CARTO::SGMAP::QuartiersPrioritaires::Adapter.new(
coordinate.map { |element| [element['lng'], element['lat']] }
@ -31,7 +31,7 @@ class ModuleApiCartoService
}
end
def self.generate_cadastre coordinates
def self.generate_cadastre(coordinates)
coordinates.flat_map do |coordinate|
CARTO::SGMAP::Cadastre::Adapter.new(
coordinate.map { |element| [element['lng'], element['lat']] }

View file

@ -1,5 +1,5 @@
class NumberService
def self.to_number string
def self.to_number(string)
string.to_s if Float(string) rescue nil
end
end

View file

@ -15,7 +15,7 @@ class PiecesJustificativesService
.compact()
end
def self.upload_one! dossier, user, params
def self.upload_one!(dossier, user, params)
content = params[:piece_justificative][:content]
if ClamavService.safe_file? content.path
pj = PieceJustificative.new(content: content,

View file

@ -1,5 +1,5 @@
class PrevisualisationService
def self.delete_all_champs dossier
def self.delete_all_champs(dossier)
Champ.where(dossier_id: dossier.id, type_de_champ_id: dossier.procedure.types_de_champ.ids).delete_all
end
end

View file

@ -1,7 +1,7 @@
class RenderPartialService
attr_accessor :controller, :method
def initialize controller, method
def initialize(controller, method)
@controller = controller
@method = method
end
@ -14,7 +14,7 @@ class RenderPartialService
retrieve_left_panel
end
def self.left_panel_exist? left_panel_url
def self.left_panel_exist?(left_panel_url)
file = left_panel_url.split('/').last
File.exist?(Rails.root.join('app','views', 'layouts', 'left_panels', "_#{file}.html.haml"))

View file

@ -1,5 +1,5 @@
class SwitchDeviseProfileService
def initialize warden
def initialize(warden)
@warden = warden
end

View file

@ -1,5 +1,5 @@
class SyncCredentialsService
def initialize klass, email_before_last_save, email, encrypted_password
def initialize(klass, email_before_last_save, email, encrypted_password)
@klass = klass
@email_before_last_save = email_before_last_save
@email = email

View file

@ -72,7 +72,7 @@ class TypesDeChampService
(tdca[:order_place].to_i + 1) != tdca[:custom_order_place].to_i
end
def self.clean_value value
def self.clean_value(value)
value.split("\r\n").map{ |v| v.strip }.join("\r\n")
end
end

View file

@ -1,5 +1,5 @@
class UserRoutesAuthorizationService
def self.authorized_route? controller, dossier
def self.authorized_route?(controller, dossier)
auth = controller.route_authorization
auth[:states].include?(dossier.state.to_sym) &&

View file

@ -0,0 +1,41 @@
<% content_for(:title) do %>
<%= display_resource_name('Demandes') %>
<% end %>
<header class="main-content__header" role="banner">
<h1 class="main-content__page-title" id="page-title">
<%= content_for(:title) %>
</h1>
</header>
<section class="main-content__body main-content__body--flush">
<table>
<thead>
<% keys = @pending_demandes.first.keys %>
<tr>
<% keys.each do |key| %>
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
<%= key %>
</th>
<% end %>
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
</th>
</thead>
<tbody>
<% @pending_demandes.each do |demande| %>
<tr>
<% keys.each do |key| %>
<td class="cell-data cell-data--string">
<%= demande[key] %>
</td>
<% end %>
<td class="cell-data cell-data--string">
<%= button_to('Créer',
manager_demandes_create_administrateur_path,
params: { administrateur: { email: demande[:email], person_id: demande[:person_id] } }) %>
</td>
</tr>
<% end %>
</tbody>
</table>
</section>

View file

@ -10,6 +10,9 @@ Rails.application.routes.draw do
post 'reinvite', on: :member
end
resources :demandes, only: [:index]
post 'demandes/create_administrateur'
authenticate :administration do
match "/delayed_job" => DelayedJobWeb, :anchor => false, :via => [:get, :post]
end

View file

@ -19,7 +19,7 @@ class BuildDefaultPreferenceListDossier < ActiveRecord::Migration
end
end
def valid_couple_table_attr? table, column
def valid_couple_table_attr?(table, column)
couples = [
{
table: :dossier,
@ -110,7 +110,7 @@ class BuildDefaultPreferenceListDossier < ActiveRecord::Migration
}
end
def self.create_column libelle, table, attr, attr_decorate, bootstrap_lg
def self.create_column(libelle, table, attr, attr_decorate, bootstrap_lg)
{
libelle: libelle,
table: table,

View file

@ -3,7 +3,7 @@ class ResetAllPreferenceListDossier < ActiveRecord::Migration
belongs_to :gestionnaire
belongs_to :procedure
def self.available_columns_for procedure_id = nil
def self.available_columns_for(procedure_id = nil)
columns = {
dossier: columns_dossier,
procedure: columns_procedure,
@ -78,7 +78,7 @@ class ResetAllPreferenceListDossier < ActiveRecord::Migration
}
end
def self.create_column libelle, table, attr, attr_decorate, bootstrap_lg
def self.create_column(libelle, table, attr, attr_decorate, bootstrap_lg)
{
libelle: libelle,
table: table,
@ -95,7 +95,7 @@ class ResetAllPreferenceListDossier < ActiveRecord::Migration
has_many :assign_to, dependent: :destroy
has_many :procedures, through: :assign_to
def build_default_preferences_list_dossier procedure_id = nil
def build_default_preferences_list_dossier(procedure_id = nil)
PreferenceListDossier.available_columns_for(procedure_id).each do |table|
table.second.each do |column|
if valid_couple_table_attr? table.first, column.first
@ -117,7 +117,7 @@ class ResetAllPreferenceListDossier < ActiveRecord::Migration
private
def valid_couple_table_attr? table, column
def valid_couple_table_attr?(table, column)
couples = [
{
table: :dossier,

View file

@ -26,7 +26,7 @@ namespace :'2017_10_30_copy_commentaire_piece_justificative_to_file' do
return name.mb_chars.to_s
end
def process_commentaire commentaire
def process_commentaire(commentaire)
puts "Processing commentaire #{commentaire.id}"
if commentaire.piece_justificative.present?
# https://github.com/carrierwaveuploader/carrierwave#uploading-files-from-a-remote-location

View file

@ -17,8 +17,7 @@ describe InvitesController, type: :controller do
let(:signed_in_profile) { create(:gestionnaire) }
shared_examples_for "he can not create invitation" do
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
it { expect { subject rescue nil }.to change(InviteGestionnaire, :count).by(0) }
it { expect { subject rescue nil }.to change(Invite, :count).by(0) }
end
context 'when gestionnaire has no access to dossier' do
@ -36,18 +35,47 @@ describe InvitesController, type: :controller do
signed_in_profile.procedures << dossier.procedure
end
it { expect { subject }.to change(InviteGestionnaire, :count).by(1) }
it_behaves_like "he can not create invitation"
context 'when is a user who is loged' do
let(:user) { create(:user) }
before do
sign_in create(:user)
dossier.update(user: user)
sign_in(user)
end
it { expect { subject }.to change(InviteGestionnaire, :count).by(1) }
it { expect { subject }.to change(InviteUser, :count).by(1) }
end
end
end
context "when user is signed_in" do
let(:signed_in_profile) { create(:user) }
shared_examples_for "he can not create a invite" do
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
it { expect { subject rescue nil }.to change(InviteUser, :count).by(0) }
end
context 'when user has no access to dossier' do
it_behaves_like "he can not create a invite"
end
context 'when user is invited on dossier' do
before { Invite.create(user: signed_in_profile, email: signed_in_profile.email, dossier: dossier) }
it_behaves_like "he can not create a invite"
end
context 'when user has access to dossier' do
before do
dossier.update(user: signed_in_profile)
end
it { expect { subject }.to change(InviteUser, :count).by(1) }
context 'when email is assign to an user' do
let! (:user) { create(:user, email: email) }
let! (:user_invite) { create(:user, email: email) }
before do
subject
@ -62,7 +90,7 @@ describe InvitesController, type: :controller do
end
end
it { expect(invite.user).to eq user }
it { expect(invite.user).to eq user_invite }
it { expect(flash[:notice]).to be_present }
end
@ -124,32 +152,5 @@ describe InvitesController, type: :controller do
end
end
end
context "when user is signed_in" do
let(:signed_in_profile) { create(:user) }
shared_examples_for "he can not create a invite" do
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
it { expect { subject rescue nil }.to change(InviteUser, :count).by(0) }
end
context 'when user has no access to dossier' do
it_behaves_like "he can not create a invite"
end
context 'when user is invited on dossier' do
before { Invite.create(user: signed_in_profile, email: signed_in_profile.email, dossier: dossier) }
it_behaves_like "he can not create a invite"
end
context 'when user has access to dossier' do
before do
dossier.update(user: signed_in_profile)
end
it { expect { subject }.to change(InviteUser, :count).by(1) }
end
end
end
end