Merge pull request #8193 from demarches-simplifiees/export-result-filter

ETQ admin, je peux exporter la liste des demarches (filtrées ou non)
This commit is contained in:
krichtof 2022-12-16 15:59:27 +01:00 committed by GitHub
commit 4a169e1a5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 131 additions and 39 deletions

View file

@ -28,4 +28,10 @@
.main-filter-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
.actions {
display: flex;
justify-content: flex-end;
}
}

View file

@ -1,6 +1,7 @@
module Administrateurs
class ProceduresController < AdministrateurController
layout 'all', only: [:all, :administrateurs]
respond_to :html, :xlsx
before_action :retrieve_procedure, only: [:champs, :annotations, :modifications, :edit, :zones, :monavis, :update_monavis, :jeton, :update_jeton, :publication, :publish, :transfert, :close, :allow_expert_review, :experts_require_administrateur_invitation, :reset_draft]
before_action :draft_valid?, only: [:apercu]
@ -331,14 +332,34 @@ module Administrateurs
@procedure = Procedure.includes(draft_revision: { revision_types_de_champ_public: :type_de_champ }).find(@procedure.id)
end
def detail
@procedure = Procedure.find(params[:id])
render turbo_stream: [
turbo_stream.remove("procedure_detail_#{@procedure.id}"),
turbo_stream.replace("procedure_#{@procedure.id}", partial: "detail", locals: { procedure: @procedure, show_detail: params[:show_detail] })
]
end
def all
@filter = ProceduresFilter.new(current_administrateur, params)
@procedures = paginate(filter_procedures(@filter), published_at: :desc)
all_procedures = filter_procedures(@filter).map { |p| ProcedureDetail.new(p) }
respond_to do |format|
format.html do
all_procedures = Kaminari.paginate_array(all_procedures.to_a, offset: 0, limit: ITEMS_PER_PAGE, total_count: all_procedures.count)
@procedures = all_procedures.page(params[:page]).per(25)
end
format.xlsx do
render xlsx: ProcedureDetail.to_xlsx(instances: all_procedures),
filename: "demarches-#{@filter}"
end
end
end
def administrateurs
@filter = ProceduresFilter.new(current_administrateur, params)
@admins = Administrateur.includes(:user, :procedures).where(id: AdministrateursProcedure.where(procedure: filter_procedures(@filter)).select(:administrateur_id))
pids = AdministrateursProcedure.select(:administrateur_id).where(procedure: filter_procedures(@filter).map { |p| p["id"] })
@admins = Administrateur.includes(:user, :procedures).where(id: pids)
@admins = @admins.where('unaccent(users.email) ILIKE unaccent(?)', "%#{@filter.email}%") if @filter.email.present?
@admins = paginate(@admins, 'users.email')
end
@ -346,12 +367,15 @@ module Administrateurs
private
def filter_procedures(filter)
procedures_result = Procedure.joins(:procedures_zones).publiees_ou_closes
procedures_result = Procedure.select(:id).joins(:procedures_zones).distinct.publiees_ou_closes
procedures_result = procedures_result.where(procedures_zones: { zone_id: filter.zone_ids }) if filter.zone_ids.present?
procedures_result = procedures_result.where(aasm_state: filter.statuses) if filter.statuses.present?
procedures_result = procedures_result.where('published_at >= ?', filter.from_publication_date) if filter.from_publication_date.present?
procedures_result = procedures_result.where('unaccent(libelle) ILIKE unaccent(?)', "%#{filter.libelle}%") if filter.libelle.present?
procedures_result
procedures_sql = procedures_result.to_sql
sql = "select id, libelle, published_at, aasm_state, count(administrateurs_procedures.administrateur_id) as admin_count from administrateurs_procedures inner join procedures on procedures.id = administrateurs_procedures.procedure_id where procedures.id in (#{procedures_sql}) group by procedures.id order by published_at desc"
ActiveRecord::Base.connection.execute(sql)
end
def paginate(result, ordered_by)

View file

@ -0,0 +1,9 @@
class ProcedureDetail < OpenStruct
include SpreadsheetArchitect
def spreadsheet_columns
[:id, :libelle, :published_at, :aasm_state, :admin_count].map do |attribute|
[I18n.t(attribute, scope: 'activerecord.attributes.procedure_export'), attribute]
end
end
end

View file

@ -60,4 +60,14 @@ class ProceduresFilter
params.to_h.merge(filter => new_filter)
end
end
def to_s
filters = []
filters << selected_zones&.map { |zone| zone.current_label.parameterize }
filters << libelle&.parameterize
filters << email
filters << "from-#{from_publication_date}" if from_publication_date
filters << statuses
filters.compact.join('-')
end
end

View file

@ -0,0 +1,21 @@
%tr.procedure{ id: "procedure_#{procedure.id}" }
%td
= button_to detail_admin_procedure_path(procedure["id"]), params: show_detail ? {} : { show_detail: true }, method: :get, title: 'Cacher les détails', class: [ show_detail ? 'fr-icon-subtract-line':'fr-icon-add-line', "fr-icon--sm fr-mr-1w fr-mb-1w fr-text-action-high--blue-france fr-btn fr-btn--tertiary-no-outline"] do
Cacher les détails
%td= procedure.libelle
%td= procedure.id
%td= procedure.administrateurs.count
%td= t procedure.aasm_state, scope: 'activerecord.attributes.procedure.aasm_state'
%td= l(procedure.published_at, format: :message_date_without_time)
- if show_detail
%tr.procedure{ id: "procedure_detail_#{procedure.id}" }
%td.fr-highlight--beige-gris-galet{ colspan: '6' }
.fr-container
.fr-grid-row
.fr-col-6
- procedure.zones.uniq.each do |zone|
= zone.label_at(procedure.published_or_created_at)
.fr-col-6
- procedure.administrateurs.uniq.each do |admin|
= admin.email

View file

@ -9,7 +9,7 @@
= f.label 'email', 'Recercher des administrateurs par email', class: 'fr-label'
= f.search_field 'email', size: 40, class: 'fr-input'
.switch= link_to 'Voir la liste des démarches', all_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary'
.actions= link_to 'Voir la liste des démarches', all_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary'
.fr-table.fr-table--bordered
%table#all-admins
%caption

View file

@ -1,6 +1,6 @@
- content_for :results do
.main-filter-header.fr-my-3w
= form_with(url: all_admin_procedures_path, method: :get, html: {'data-autosubmit-target': 'form', role: 'search' }) do |f|
= form_with(url: all_admin_procedures_path, method: :get, html: {'data-autosubmit-target': 'form', role: 'search', class: 'search' }) do |f|
- @filter.zone_ids&.each do |zone_id|
= hidden_field_tag 'zone_ids[]', zone_id
- @filter.statuses&.each do |status|
@ -8,8 +8,10 @@
= hidden_field_tag 'from_publication_date', @filter.from_publication_date if @filter.from_publication_date.present?
= f.label :libelle, 'Rechercher des démarches par libellé', class: 'fr-label'
= f.search_field 'libelle', size: 40, class: 'fr-input'
.switch= link_to 'Voir la liste des administrateurs', administrateurs_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary'
= f.search_field 'libelle', size: 30, class: 'fr-input'
.actions
.link.fr-mx-1w= link_to 'Voir les administrateurs', administrateurs_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary'
.link.fr-mx-1w= link_to 'Exporter les résultats', all_admin_procedures_path(@filter.params.merge(format: :xlsx)), class: 'fr-btn fr-btn--secondary'
.fr-table.fr-table--bordered
%table#all-demarches
%caption
@ -38,24 +40,15 @@
%th{ scope: 'col' } Administrateurs
%th{ scope: 'col' } Statut
%th{ scope: 'col' } Date
- @procedures.each do |procedure|
%tbody{ 'data-controller': 'expand' }
%tr.procedure{ 'data-action': 'click->expand#toggle' }
%tbody{ 'data-turbo': 'true' }
- @procedures.each do |procedure|
%tr.procedure{ id: "procedure_#{procedure['id']}" }
%td
%button.fr-icon-add-line.fr-icon--sm.fr-mr-1w.fr-mb-1w.fr-text-action-high--blue-france{ 'aria-hidden': 'true', 'data-expand-target': 'icon' }
= button_to detail_admin_procedure_path(procedure["id"]), params: { show_detail: true}, method: :get, title: 'Afficher details', class: "fr-icon-add-line fr-icon--sm fr-mr-1w fr-mb-1w fr-text-action-high--blue-france fr-btn fr-btn--tertiary-no-outline" do
Afficher details procedure
%td= procedure.libelle
%td= procedure.id
%td= procedure.administrateurs.count
%td= t procedure.aasm_state, scope: 'activerecord.attributes.procedure.aasm_state'
%td= procedure.admin_count
%td= t procedure.aasm_state, scope: 'activerecord.values.procedure.aasm_state'
%td= l(procedure.published_at, format: :message_date_without_time)
%tr.hidden{ 'data-expand-target': 'content' }
%td.fr-highlight--beige-gris-galet{ colspan: '6' }
.fr-container
.fr-grid-row
.fr-col-6
- procedure.zones.uniq.each do |zone|
= zone.label_at(procedure.published_or_created_at)
.fr-col-6
- procedure.administrateurs.uniq.each do |admin|
= admin.email
.fr-mt-2w= paginate @procedures, views_prefix: 'administrateurs'

View file

@ -0,0 +1 @@
= turbo_stream.after("procedure_#{@procedure.id}", partial: "detail", locals: { procedure: @procedure })

View file

@ -27,6 +27,12 @@ en:
without_continuation_mail: File sorted with no further action notification email
attestation_template: Attestation template
draft_revision: The form
procedure_export:
id: Id
libelle: Libelle
published_at: Publication date
aasm_state: Status
admin_count: Administrators count
errors:
models:
procedure:

View file

@ -10,6 +10,11 @@ fr:
organisation: Organisme
duree_conservation_dossiers_dans_ds: Durée de conservation des dossiers sur demarches-simplifiees.fr (choisi par un usager)
max_duree_conservation_dossiers_dans_ds: Durée de conservation des dossiers maximum (autorisé par un super admin de DS)
id: Id
libelle: Libelle
published_at: 'Date de publication'
aasm_state: 'Statut'
admin_count: 'Nb administrateurs'
aasm_state:
brouillon: Brouillon
publiee: Publiée
@ -27,6 +32,12 @@ fr:
without_continuation_mail: Lemail de notification de classement sans suite de dossier
attestation_template: Le modèle dattestation
draft_revision: Le formulaire
procedure_export:
id: Id
libelle: Libelle
published_at: 'Date de publication'
aasm_state: 'Statut'
admin_count: 'Nb administrateurs'
errors:
models:
procedure:

View file

@ -440,6 +440,7 @@ Rails.application.routes.draw do
end
member do
get 'detail'
get 'apercu'
get 'champs'
get 'zones'

View file

@ -95,15 +95,25 @@ describe Administrateurs::ProceduresController, type: :controller do
it { expect(subject.status).to eq(200) }
context 'for export' do
subject { get :all, format: :xlsx }
it 'exports result in xlsx' do
allow(ProcedureDetail).to receive(:to_xlsx)
subject
expect(ProcedureDetail).to have_received(:to_xlsx)
end
end
it 'display published or closed procedures' do
subject
expect(assigns(:procedures)).to include(published_procedure)
expect(assigns(:procedures)).to include(closed_procedure)
expect(assigns(:procedures).any? { |p| p.id == published_procedure.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == closed_procedure.id }).to be_truthy
end
it 'doesnt display draft procedures' do
subject
expect(assigns(:procedures)).not_to include(draft_procedure)
expect(assigns(:procedures).any? { |p| p.id == draft_procedure.id }).to be_falsey
end
context "for specific zones" do
@ -116,8 +126,8 @@ describe Administrateurs::ProceduresController, type: :controller do
it 'display only procedures for specified zones' do
subject
expect(assigns(:procedures)).to include(procedure2)
expect(assigns(:procedures)).not_to include(procedure1)
expect(assigns(:procedures).any? { |p| p.id == procedure2.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == procedure1.id }).to be_falsey
end
end
@ -127,14 +137,14 @@ describe Administrateurs::ProceduresController, type: :controller do
it 'display only published procedures' do
get :all, params: { statuses: ['publiee'] }
expect(assigns(:procedures)).to include(procedure1)
expect(assigns(:procedures)).not_to include(procedure2)
expect(assigns(:procedures).any? { |p| p.id == procedure1.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == procedure2.id }).to be_falsey
end
it 'display only closed procedures' do
get :all, params: { statuses: ['close'] }
expect(assigns(:procedures)).to include(procedure2)
expect(assigns(:procedures)).not_to include(procedure1)
expect(assigns(:procedures).any? { |p| p.id == procedure2.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == procedure1.id }).to be_falsey
end
end
@ -146,9 +156,9 @@ describe Administrateurs::ProceduresController, type: :controller do
it 'display only procedures published after specific date' do
get :all, params: { from_publication_date: after }
expect(assigns(:procedures)).to include(procedure1)
expect(assigns(:procedures)).to include(procedure2)
expect(assigns(:procedures)).not_to include(procedure3)
expect(assigns(:procedures).any? { |p| p.id == procedure1.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == procedure2.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == procedure3.id }).to be_falsey
end
end
@ -159,9 +169,9 @@ describe Administrateurs::ProceduresController, type: :controller do
it 'returns procedures with specific terms in libelle' do
get :all, params: { libelle: 'entrepreneur' }
expect(assigns(:procedures)).to include(procedure2)
expect(assigns(:procedures)).to include(procedure3)
expect(assigns(:procedures)).not_to include(procedure1)
expect(assigns(:procedures).any? { |p| p.id == procedure2.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == procedure3.id }).to be_truthy
expect(assigns(:procedures).any? { |p| p.id == procedure1.id }).to be_falsey
end
end
end