refactor: always load full dossier

This commit is contained in:
simon lehericey 2024-11-13 11:01:10 +01:00
parent fe0a396dc6
commit c415b066b9
No known key found for this signature in database
GPG key ID: CDE670D827C7B3C5
4 changed files with 47 additions and 60 deletions

View file

@ -105,7 +105,7 @@ module Instructeurs
.per(ITEMS_PER_PAGE) .per(ITEMS_PER_PAGE)
@projected_dossiers = DossierProjectionService.project(@filtered_sorted_paginated_ids, procedure_presentation.displayed_columns) @projected_dossiers = DossierProjectionService.project(@filtered_sorted_paginated_ids, procedure_presentation.displayed_columns)
@disable_checkbox_all = @projected_dossiers.all? { _1.batch_operation_id.present? } @disable_checkbox_all = @projected_dossiers.all? { _1.dossier.batch_operation_id.present? }
@batch_operations = BatchOperation.joins(:groupe_instructeurs) @batch_operations = BatchOperation.joins(:groupe_instructeurs)
.where(groupe_instructeurs: current_instructeur.groupe_instructeurs.where(procedure_id: @procedure.id)) .where(groupe_instructeurs: current_instructeur.groupe_instructeurs.where(procedure_id: @procedure.id))

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class DossierProjectionService class DossierProjectionService
class DossierProjection < Struct.new(:dossier_id, :state, :archived, :hidden_by_user_at, :hidden_by_administration_at, :hidden_by_reason, :for_tiers, :batch_operation_id, :sva_svr_decision_on, :corrections, :columns) do class DossierProjection < Struct.new(:dossier, :corrections, :columns) do
def pending_correction? def pending_correction?
return false if corrections.blank? return false if corrections.blank?
@ -51,17 +51,9 @@ class DossierProjectionService
end end
champ_value = champ_value_formatter(dossiers_ids, fields) champ_value = champ_value_formatter(dossiers_ids, fields)
state_field = { TABLE => 'self', COLUMN => 'state' }
archived_field = { TABLE => 'self', COLUMN => 'archived' }
batch_operation_field = { TABLE => 'self', COLUMN => 'batch_operation_id' }
hidden_by_user_at_field = { TABLE => 'self', COLUMN => 'hidden_by_user_at' }
hidden_by_administration_at_field = { TABLE => 'self', COLUMN => 'hidden_by_administration_at' }
hidden_by_reason_field = { TABLE => 'self', COLUMN => 'hidden_by_reason' }
for_tiers_field = { TABLE => 'self', COLUMN => 'for_tiers' }
sva_svr_decision_on_field = { TABLE => 'self', COLUMN => 'sva_svr_decision_on' }
dossier_corrections = { TABLE => 'dossier_corrections', COLUMN => 'resolved_at' } dossier_corrections = { TABLE => 'dossier_corrections', COLUMN => 'resolved_at' }
([state_field, archived_field, sva_svr_decision_on_field, hidden_by_user_at_field, hidden_by_administration_at_field, hidden_by_reason_field, for_tiers_field, batch_operation_field, dossier_corrections] + fields) ([dossier_corrections] + fields)
.each { |f| f[:id_value_h] = {} } .each { |f| f[:id_value_h] = {} }
.group_by { |f| f[TABLE] } # one query per table .group_by { |f| f[TABLE] } # one query per table
.each do |table, fields| .each do |table, fields|
@ -89,7 +81,7 @@ class DossierProjectionService
.each do |id, *columns| .each do |id, *columns|
fields.zip(columns).each do |field, value| fields.zip(columns).each do |field, value|
# SVA must remain a date: in other column we compute remaining delay with it # SVA must remain a date: in other column we compute remaining delay with it
field[:id_value_h][id] = if value.respond_to?(:strftime) && field != sva_svr_decision_on_field field[:id_value_h][id] = if value.respond_to?(:strftime)
I18n.l(value.to_date) I18n.l(value.to_date)
else else
value value
@ -171,17 +163,11 @@ class DossierProjectionService
end end
end end
dossiers = Dossier.find(dossiers_ids)
dossiers_ids.map do |dossier_id| dossiers_ids.map do |dossier_id|
DossierProjection.new( DossierProjection.new(
dossier_id, dossiers.find { _1.id == dossier_id },
state_field[:id_value_h][dossier_id],
archived_field[:id_value_h][dossier_id],
hidden_by_user_at_field[:id_value_h][dossier_id],
hidden_by_administration_at_field[:id_value_h][dossier_id],
hidden_by_reason_field[:id_value_h][dossier_id],
for_tiers_field[:id_value_h][dossier_id],
batch_operation_field[:id_value_h][dossier_id],
sva_svr_decision_on_field[:id_value_h][dossier_id],
dossier_corrections[:id_value_h][dossier_id], dossier_corrections[:id_value_h][dossier_id],
fields.map { |f| f[:id_value_h][dossier_id] } fields.map { |f| f[:id_value_h][dossier_id] }
) )

View file

@ -110,70 +110,71 @@
= render Dossiers::BatchSelectMoreComponent.new(dossiers_count: @dossiers_count, filtered_sorted_ids: @filtered_sorted_ids) = render Dossiers::BatchSelectMoreComponent.new(dossiers_count: @dossiers_count, filtered_sorted_ids: @filtered_sorted_ids)
- @projected_dossiers.each do |p| - @projected_dossiers.each do |p|
- path = instructeur_dossier_path(@procedure, p.dossier_id) - dossier = p.dossier
%tr{ class: class_names("file-hidden-by-user" => p.hidden_by_user_at.present?), id: "table-dossiers-row-#{p.dossier_id}", "aria-selected" => "false", "data-row-key" => p.dossier_id } - path = instructeur_dossier_path(@procedure, dossier.id)
%tr{ class: class_names("file-hidden-by-user" => dossier.hidden_by_user_at.present?), id: "table-dossiers-row-#{dossier.id}", "aria-selected" => "false", "data-row-key" => dossier.id }
- if batch_operation_component.render? - if batch_operation_component.render?
%th.fr-cell--fixed{ scope: 'row' } %th.fr-cell--fixed{ scope: 'row' }
.fr-checkbox-group.fr-checkbox-group--sm .fr-checkbox-group.fr-checkbox-group--sm
- if p.batch_operation_id.present? - if dossier.batch_operation_id.present?
= check_box_tag "batch_operation[dossier_ids][]", p.dossier_id, true, disabled: true, = check_box_tag "batch_operation[dossier_ids][]", dossier.id, true, disabled: true,
id: dom_id(BatchOperation.new, "checkbox_#{p.dossier_id}"), id: dom_id(BatchOperation.new, "checkbox_#{dossier.id}"),
aria: { label: t('views.instructeurs.dossiers.batch_operation.disabled', dossier_id: p.dossier_id) }, aria: { label: t('views.instructeurs.dossiers.batch_operation.disabled', dossier_id: dossier.id) },
data: { "fr-row-select" => "true" } data: { "fr-row-select" => "true" }
- else - else
= check_box_tag "batch_operation[dossier_ids][]", p.dossier_id, false, = check_box_tag "batch_operation[dossier_ids][]", dossier.id, false,
data: { batch_operation_target: "input", action: "batch-operation#onCheckOne", operations: batch_operation_component.operations_for_dossier(p).join(','), "fr-row-select" => "true" }, data: { batch_operation_target: "input", action: "batch-operation#onCheckOne", operations: batch_operation_component.operations_for_dossier(dossier).join(','), "fr-row-select" => "true" },
form: dom_id(BatchOperation.new), id: dom_id(BatchOperation.new, "checkbox_#{p.dossier_id}"), form: dom_id(BatchOperation.new), id: dom_id(BatchOperation.new, "checkbox_#{dossier.id}"),
aria: { label: t('views.instructeurs.dossiers.batch_operation.enabled', dossier_id: p.dossier_id) } aria: { label: t('views.instructeurs.dossiers.batch_operation.enabled', dossier_id: dossier.id) }
= label_tag dom_id(BatchOperation.new, "checkbox_#{p.dossier_id}"), "Sélectionner le dossier #{p.dossier_id}", class: 'fr-label' = label_tag dom_id(BatchOperation.new, "checkbox_#{dossier.id}"), "Sélectionner le dossier #{dossier.id}", class: 'fr-label'
%td.fr-cell--numeric %td.fr-cell--numeric
- if p.hidden_by_administration_at.present? - if dossier.hidden_by_administration_at.present?
%span= p.dossier_id %span= dossier.id
- else - else
%a.fr-link.relative{ href: path } %a.fr-link.relative{ href: path }
= p.dossier_id = dossier.id
- if @not_archived_notifications_dossier_ids.include?(p.dossier_id) - if @not_archived_notifications_dossier_ids.include?(dossier.id)
%span.notifications{ 'aria-label': 'notifications' } %span.notifications{ 'aria-label': 'notifications' }
- p.columns.each do |column| - p.columns.each do |column|
%td.fr-cell--multiline %td.fr-cell--multiline
- if p.hidden_by_administration_at.present? - if dossier.hidden_by_administration_at.present?
%span %span
= column.is_a?(Hash) ? tags_label(column[:value]) : column = column.is_a?(Hash) ? tags_label(column[:value]) : column
- if p.hidden_by_user_at.present? - if dossier.hidden_by_user_at.present?
= "- #{t("views.instructeurs.dossiers.deleted_reason.#{p.hidden_by_reason}")}" = "- #{t("views.instructeurs.dossiers.deleted_reason.#{dossier.hidden_by_reason}")}"
- else - else
%a{ href: path } %a{ href: path }
= column.is_a?(Hash) ? tags_label(column[:value]) : column = column.is_a?(Hash) ? tags_label(column[:value]) : column
= "- #{t("views.instructeurs.dossiers.deleted_reason.#{p.hidden_by_reason}")}" if p.hidden_by_user_at.present? = "- #{t("views.instructeurs.dossiers.deleted_reason.#{dossier.hidden_by_reason}")}" if dossier.hidden_by_user_at.present?
%td %td
- status = [status_badge(p.state)] - status = [status_badge(dossier.state)]
- if p.pending_correction? - if p.pending_correction?
- status << pending_correction_badge(:for_instructeur, html_class: "fr-mt-1v") - status << pending_correction_badge(:for_instructeur, html_class: "fr-mt-1v")
- elsif p.state.to_sym == :en_construction && p.resolved_corrections? - elsif dossier.state.to_sym == :en_construction && p.resolved_corrections?
- status << correction_resolved_badge(html_class: "fr-mt-1v") - status << correction_resolved_badge(html_class: "fr-mt-1v")
= link_to_if(p.hidden_by_administration_at.blank?, safe_join(status), path, class: "flex column") = link_to_if(dossier.hidden_by_administration_at.blank?, safe_join(status), path, class: "flex column")
- if @procedure.sva_svr_enabled? - if @procedure.sva_svr_enabled?
%td %td
%span %span
= link_to_if p.hidden_by_administration_at.blank?, render(Instructeurs::SVASVRDecisionBadgeComponent.new(projection_or_dossier: p, procedure: @procedure)), path = link_to_if dossier.hidden_by_administration_at.blank?, render(Instructeurs::SVASVRDecisionBadgeComponent.new(projection_or_dossier: dossier, procedure: @procedure)), path
%td.follow-col %td.follow-col
%ul.fr-btns-group.fr-btns-group--sm.fr-btns-group--inline.fr-btns-group--icon-right %ul.fr-btns-group.fr-btns-group--sm.fr-btns-group--inline.fr-btns-group--icon-right
= render partial: 'instructeurs/procedures/dossier_actions', locals: { procedure_id: @procedure.id, = render partial: 'instructeurs/procedures/dossier_actions', locals: { procedure_id: @procedure.id,
dossier_id: p.dossier_id, dossier_id: dossier.id,
state: p.state, state: dossier.state,
archived: p.archived, archived: dossier.archived,
dossier_is_followed: @followed_dossiers_id.include?(p.dossier_id), dossier_is_followed: @followed_dossiers_id.include?(dossier.id),
close_to_expiration: @statut == 'expirant', close_to_expiration: @statut == 'expirant',
hidden_by_administration: @statut == 'supprimes', hidden_by_administration: @statut == 'supprimes',
hidden_by_expired: p.hidden_by_reason == 'expired', hidden_by_expired: dossier.hidden_by_reason == 'expired',
sva_svr: @procedure.sva_svr_enabled?, sva_svr: @procedure.sva_svr_enabled?,
has_blocking_pending_correction: @procedure.feature_enabled?(:blocking_pending_correction) && p.pending_correction?, has_blocking_pending_correction: @procedure.feature_enabled?(:blocking_pending_correction) && dossier.pending_correction?,
turbo: false, turbo: false,
with_menu: false } with_menu: false }

View file

@ -29,17 +29,17 @@ describe DossierProjectionService do
it 'respects the dossiers_ids order, returns state, archived and nil for empty result' do it 'respects the dossiers_ids order, returns state, archived and nil for empty result' do
expect(result.length).to eq(3) expect(result.length).to eq(3)
expect(result[0].dossier_id).to eq(dossier_3.id) expect(result[0].dossier.id).to eq(dossier_3.id)
expect(result[1].dossier_id).to eq(dossier_1.id) expect(result[1].dossier.id).to eq(dossier_1.id)
expect(result[2].dossier_id).to eq(dossier_2.id) expect(result[2].dossier.id).to eq(dossier_2.id)
expect(result[0].state).to eq('en_instruction') expect(result[0].dossier.state).to eq('en_instruction')
expect(result[1].state).to eq('brouillon') expect(result[1].dossier.state).to eq('brouillon')
expect(result[2].state).to eq('en_construction') expect(result[2].dossier.state).to eq('en_construction')
expect(result[0].archived).to be false expect(result[0].dossier.archived).to be false
expect(result[1].archived).to be false expect(result[1].dossier.archived).to be false
expect(result[2].archived).to be true expect(result[2].dossier.archived).to be true
expect(result[0].columns[0]).to be nil expect(result[0].columns[0]).to be nil
expect(result[1].columns[0]).to eq('champ_1') expect(result[1].columns[0]).to eq('champ_1')
@ -66,7 +66,7 @@ describe DossierProjectionService do
it 'returns champ value' do it 'returns champ value' do
expect(result.length).to eq(1) expect(result.length).to eq(1)
expect(result[0].dossier_id).to eq(dossier.id) expect(result[0].dossier.id).to eq(dossier.id)
expect(result[0].columns[0]).to eq('Châteldon (63290)') expect(result[0].columns[0]).to eq('Châteldon (63290)')
end end
end end