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

View file

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

View file

@ -180,6 +180,15 @@ class ProcedureRevision < ApplicationRecord
tdcs_as_json
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
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 :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
def self.load(options)

View file

@ -1,7 +1,7 @@
class TypesDeChamp::TypeDeChampBase
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_MEDIUM = 1.minute.in_seconds

View file

@ -8,10 +8,15 @@
%h1.procedure-title
= procedure.libelle
- if procedure.auto_archive_on
%details.procedure-auto-archive
%summary
- 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
%details.procedure-configuration.procedure-configuration--auto-archive
%summary
%span.icon.edit
%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)}.

View file

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

View file

@ -524,3 +524,5 @@ en:
dossiers_count: "Nb files"
weekly_distribution: "Weekly distribution"
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"
weekly_distribution: "Répartition par semaine"
weekly_distribution_details: "au cours des 6 derniers mois"
procedure_description:
estimated_fill_duration: "Temps de remplissage estimé : %{estimated_minutes} mn"

View file

@ -1,4 +1,5 @@
RSpec.describe ProcedureHelper, type: :helper do
describe '#procedure_auto_archive_datetime' do
let(:auto_archive_date) { Time.zone.local(2020, 8, 2, 12, 00) }
let(:procedure) { build(:procedure, auto_archive_on: auto_archive_date) }
@ -7,4 +8,25 @@ RSpec.describe ProcedureHelper, type: :helper 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)")
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

View file

@ -545,4 +545,52 @@ describe ProcedureRevision do
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

View file

@ -22,4 +22,11 @@ describe 'shared/_procedure_description.html.haml', type: :view do
expect(rendered).to have_text('Date limite')
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