app: display estimated fill duration on procedure description

This commit is contained in:
Pierre de La Morinerie 2022-05-24 09:39:03 +00:00
parent 3b57d98692
commit 3e91a16895
12 changed files with 120 additions and 16 deletions

View file

@ -44,15 +44,13 @@ $procedure-description-line-height: 22px;
} }
} }
.procedure-auto-archive { .procedure-configuration {
cursor: pointer; font-size: 20px;
margin-bottom: 32px; margin-bottom: 32px;
}
p { .procedure-configuration--auto-archive {
padding-top: 8px; cursor: pointer;
font-size: 16px;
}
summary { summary {
font-size: 20px; font-size: 20px;
@ -64,6 +62,11 @@ $procedure-description-line-height: 22px;
display: none; display: none;
} }
} }
p {
padding-top: 8px;
font-size: 16px;
}
} }
.procedure-auto-archive-title { .procedure-auto-archive-title {

View file

@ -82,4 +82,9 @@ module ProcedureHelper
return "//#{uri}" if uri.scheme.nil? return "//#{uri}" if uri.scheme.nil?
uri.to_s uri.to_s
end end
def estimated_fill_duration_minutes(procedure)
minutes = (procedure.active_revision.estimated_fill_duration / 60.0).round
[1, minutes].max
end
end end

View file

@ -180,6 +180,15 @@ class ProcedureRevision < ApplicationRecord
tdcs_as_json tdcs_as_json
end end
# Estimated duration to fill the form, in seconds
def estimated_fill_duration
tdc_durations = types_de_champ_public.fillable.map do |tdc|
duration = tdc.estimated_fill_duration(self)
tdc.mandatory ? duration : duration / 2
end
tdc_durations.sum
end
private private
def children_types_de_champ_as_json(tdcs_as_json, parent_tdcs) def children_types_de_champ_as_json(tdcs_as_json, parent_tdcs)

View file

@ -66,7 +66,7 @@ class TypeDeChamp < ApplicationRecord
has_one :revision, through: :revision_type_de_champ has_one :revision, through: :revision_type_de_champ
has_one :procedure, through: :revision has_one :procedure, through: :revision
delegate :tags_for_template, :libelle_for_export, to: :dynamic_type delegate :estimated_fill_duration, :tags_for_template, :libelle_for_export, to: :dynamic_type
class WithIndifferentAccess class WithIndifferentAccess
def self.load(options) def self.load(options)

View file

@ -1,7 +1,7 @@
class TypesDeChamp::TypeDeChampBase class TypesDeChamp::TypeDeChampBase
include ActiveModel::Validations include ActiveModel::Validations
delegate :description, :libelle, :stable_id, to: :@type_de_champ delegate :description, :libelle, :mandatory, :stable_id, to: :@type_de_champ
FILL_DURATION_SHORT = 10.seconds.in_seconds FILL_DURATION_SHORT = 10.seconds.in_seconds
FILL_DURATION_MEDIUM = 1.minute.in_seconds FILL_DURATION_MEDIUM = 1.minute.in_seconds

View file

@ -8,10 +8,15 @@
%h1.procedure-title %h1.procedure-title
= procedure.libelle = procedure.libelle
- if procedure.feature_enabled?(:procedure_estimated_fill_duration)
%p.procedure-configuration.procedure-configuration--fill-duration
%span.icon.clock
= t('shared.procedure_description.estimated_fill_duration', estimated_minutes: estimated_fill_duration_minutes(procedure))
- if procedure.auto_archive_on - if procedure.auto_archive_on
%details.procedure-auto-archive %details.procedure-configuration.procedure-configuration--auto-archive
%summary %summary
%span.icon.clock %span.icon.edit
%span.procedure-auto-archive-title Date limite : #{procedure_auto_archive_date(procedure)} %span.procedure-auto-archive-title Date limite : #{procedure_auto_archive_date(procedure)}
%p Vous pouvez déposer vos dossiers jusquau #{procedure_auto_archive_datetime(procedure)}. %p Vous pouvez déposer vos dossiers jusquau #{procedure_auto_archive_datetime(procedure)}.

View file

@ -26,6 +26,7 @@ features = [
:hide_instructeur_email, :hide_instructeur_email,
:procedure_revisions, :procedure_revisions,
:procedure_routage_api, :procedure_routage_api,
:procedure_estimated_fill_duration,
:procedure_process_expired_dossiers_termine :procedure_process_expired_dossiers_termine
] ]

View file

@ -524,3 +524,5 @@ en:
dossiers_count: "Nb files" dossiers_count: "Nb files"
weekly_distribution: "Weekly distribution" weekly_distribution: "Weekly distribution"
weekly_distribution_details: "in the last 6 months" weekly_distribution_details: "in the last 6 months"
procedure_description:
estimated_fill_duration: "Estimated fill time: %{estimated_minutes} mn"

View file

@ -575,3 +575,5 @@ fr:
dossiers_count: "Nb dossiers" dossiers_count: "Nb dossiers"
weekly_distribution: "Répartition par semaine" weekly_distribution: "Répartition par semaine"
weekly_distribution_details: "au cours des 6 derniers mois" weekly_distribution_details: "au cours des 6 derniers mois"
procedure_description:
estimated_fill_duration: "Temps de remplissage estimé : %{estimated_minutes} mn"

View file

@ -1,10 +1,32 @@
RSpec.describe ProcedureHelper, type: :helper do RSpec.describe ProcedureHelper, type: :helper do
let(:auto_archive_date) { Time.zone.local(2020, 8, 2, 12, 00) } describe '#procedure_auto_archive_datetime' do
let(:procedure) { build(:procedure, auto_archive_on: auto_archive_date) } let(:auto_archive_date) { Time.zone.local(2020, 8, 2, 12, 00) }
let(:procedure) { build(:procedure, auto_archive_on: auto_archive_date) }
subject { procedure_auto_archive_datetime(procedure) } subject { procedure_auto_archive_datetime(procedure) }
it "displays the day before the auto archive date (to account for the '23h59' ending time)" do it "displays the day before the auto archive date (to account for the '23h59' ending time)" do
expect(subject).to have_text("1 août 2020 à 23 h 59 (heure de Paris)") expect(subject).to have_text("1 août 2020 à 23 h 59 (heure de Paris)")
end
end
describe '#estimated_fill_duration_minutes' do
subject { estimated_fill_duration_minutes(procedure) }
context 'with champs' do
let(:procedure) { build(:procedure, :with_yes_no, :with_piece_justificative) }
it 'rounds up the duration to the minute' do
expect(subject).to eq(2)
end
end
context 'without champs' do
let(:procedure) { build(:procedure) }
it 'never displays zero minutes' do
expect(subject).to eq(1)
end
end
end end
end end

View file

@ -545,4 +545,52 @@ describe ProcedureRevision do
end end
end end
end end
describe '#estimated_fill_duration' do
let(:mandatory) { true }
let(:types_de_champ) do
[
build(:type_de_champ_text, position: 1, mandatory: true),
build(:type_de_champ_siret, position: 2, mandatory: true),
build(:type_de_champ_piece_justificative, position: 3, mandatory: mandatory)
]
end
let(:procedure) { create(:procedure, types_de_champ: types_de_champ) }
subject { procedure.active_revision.estimated_fill_duration }
it 'sums the durations of public champs' do
expect(subject).to eq \
TypesDeChamp::TypeDeChampBase::FILL_DURATION_SHORT \
+ TypesDeChamp::TypeDeChampBase::FILL_DURATION_MEDIUM \
+ TypesDeChamp::TypeDeChampBase::FILL_DURATION_LONG
end
context 'when some champs are optional' do
let(:mandatory) { false }
it 'estimates that half of optional champs will be filled' do
expect(subject).to eq \
TypesDeChamp::TypeDeChampBase::FILL_DURATION_SHORT \
+ TypesDeChamp::TypeDeChampBase::FILL_DURATION_MEDIUM \
+ TypesDeChamp::TypeDeChampBase::FILL_DURATION_LONG / 2
end
end
context 'when there are repetitions' do
let(:types_de_champ) do
[
build(:type_de_champ_repetition, position: 1, mandatory: true, types_de_champ: [
build(:type_de_champ_text, position: 1, mandatory: true),
build(:type_de_champ_piece_justificative, position: 2, mandatory: true)
])
]
end
it 'estimates that between 2 and 3 rows will be filled for each repetition' do
row_duration = TypesDeChamp::TypeDeChampBase::FILL_DURATION_SHORT + TypesDeChamp::TypeDeChampBase::FILL_DURATION_LONG
expect(subject).to eq row_duration * 2.5
end
end
end
end end

View file

@ -22,4 +22,11 @@ describe 'shared/_procedure_description.html.haml', type: :view do
expect(rendered).to have_text('Date limite') expect(rendered).to have_text('Date limite')
end end
end end
context 'when the procedure_estimated_fill_duration feature is enabled' do
before { Flipper.enable(:procedure_estimated_fill_duration) }
after { Flipper.disable(:procedure_estimated_fill_duration) }
it { is_expected.to have_text('Temps de remplissage estimé') }
end
end end