From 7b6fc7d06f1ca3d8d96b445c840fcf002a4747dc Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Fri, 9 May 2025 18:56:14 +0300 Subject: [PATCH] add expiration duration to template preferences --- .../templates_preferences_controller.rb | 2 + app/models/template.rb | 18 +++ .../_reminder_form.html.erb | 6 +- app/views/templates_preferences/show.html.erb | 18 +++ config/locales/i18n.yml | 114 ++++++++++++++++++ lib/submissions.rb | 14 +++ lib/submissions/create_from_submitters.rb | 3 +- 7 files changed, 171 insertions(+), 4 deletions(-) diff --git a/app/controllers/templates_preferences_controller.rb b/app/controllers/templates_preferences_controller.rb index 07111a16..2c9194b7 100644 --- a/app/controllers/templates_preferences_controller.rb +++ b/app/controllers/templates_preferences_controller.rb @@ -26,6 +26,8 @@ class TemplatesPreferencesController < ApplicationController completed_notification_email_attach_documents completed_redirect_url validate_unique_submitters submitters_order require_phone_2fa + default_expire_at_duration + default_expire_at completed_notification_email_subject completed_notification_email_body completed_notification_email_enabled completed_notification_email_attach_audit] + [completed_message: %i[title body], diff --git a/app/models/template.rb b/app/models/template.rb index 28441a9a..366217fb 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -36,6 +36,24 @@ # class Template < ApplicationRecord DEFAULT_SUBMITTER_NAME = 'First Party' + EXPIRATION_DURATIONS = { + one_day: 1.day, + two_days: 2.days, + three_days: 3.days, + four_days: 4.days, + five_days: 5.days, + six_days: 6.days, + seven_days: 7.days, + eight_days: 8.days, + nine_days: 9.days, + ten_days: 10.days, + two_weeks: 14.days, + three_weeks: 21.days, + four_weeks: 28.days, + one_month: 1.month, + two_months: 2.months, + three_months: 3.months + }.with_indifferent_access.freeze belongs_to :author, class_name: 'User' belongs_to :account diff --git a/app/views/notifications_settings/_reminder_form.html.erb b/app/views/notifications_settings/_reminder_form.html.erb index fb8d2dbd..40a077b7 100644 --- a/app/views/notifications_settings/_reminder_form.html.erb +++ b/app/views/notifications_settings/_reminder_form.html.erb @@ -7,19 +7,19 @@
<%= f.fields_for :value, record do |ff| %> <%= ff.label :first_duration, t('first_reminder_in'), class: 'label truncate' %> - <%= ff.select :first_duration, durations, { include_blank: 'None' }, class: 'base-select' %> + <%= ff.select :first_duration, durations, { include_blank: t('none') }, class: 'base-select' %> <% end %>
<%= f.fields_for :value, record do |ff| %> <%= ff.label :second_duration, t('second_reminder_in'), class: 'label truncate' %> - <%= ff.select :second_duration, durations, { include_blank: 'None' }, class: 'base-select' %> + <%= ff.select :second_duration, durations, { include_blank: t('none') }, class: 'base-select' %> <% end %>
<%= f.fields_for :value, record do |ff| %> <%= ff.label :third_duration, t('third_reminder_in'), class: 'label truncate' %> - <%= ff.select :third_duration, durations, { include_blank: 'None' }, class: 'base-select' %> + <%= ff.select :third_duration, durations, { include_blank: t('none') }, class: 'base-select' %> <% end %>
diff --git a/app/views/templates_preferences/show.html.erb b/app/views/templates_preferences/show.html.erb index a1b9ffee..0fe4b5ee 100644 --- a/app/views/templates_preferences/show.html.erb +++ b/app/views/templates_preferences/show.html.erb @@ -41,6 +41,24 @@ <% end %> + <%= form_for @template, url: template_preferences_path(@template), method: :post, html: { autocomplete: 'off', class: 'mb-2' }, data: { close_on_submit: false } do |f| %> + + <%= f.fields_for :preferences, Struct.new(:default_expire_at_duration, :default_expire_at).new(*@template.preferences.values_at('default_expire_at_duration', 'default_expire_at').compact_blank) do |ff| %> +
+ <% duration_options = ::Template::EXPIRATION_DURATIONS.keys.map { |duration| [t(duration), duration] } + [[t('specified_date'), 'specified_date']] %> + <%= ff.label :default_expire_at_duration, t('default_expiration'), class: 'label' %> +
+ <%= ff.select :default_expire_at_duration, duration_options, { include_blank: t('none') }, required: false, class: 'base-select flex-1', dir: 'auto', autocomplete: 'off', onchange: "this.value == 'specified_date' ? window.template_preferences_default_expire_at.classList.remove('hidden') : [window.template_preferences_default_expire_at.classList.add('hidden'), window.template_preferences_default_expire_at.value = '', this.form.requestSubmit()]" %> + <%= ff.datetime_field :default_expire_at, required: false, class: ['base-input flex-1', ff.object.default_expire_at.blank? && 'hidden'].compact_blank.join(' '), dir: 'auto', autocomplete: 'off', onchange: 'this.value && this.form.requestSubmit()' %> +
+
+
+
+ +
+
+ <% end %> + <% end %> <%= render 'templates_code_modal/preferences' %>
diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index 0ceac2f8..7714cd35 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -717,6 +717,25 @@ en: &en name_a_z: Name A-Z recently_used: Recently used newest_first: Newest first + none: None + default_expiration: Default expiration + specified_date: Specified date + one_day: 1 day + two_days: 2 days + three_days: 3 days + four_days: 4 days + five_days: 5 days + six_days: 6 days + seven_days: 7 days + eight_days: 8 days + nine_days: 9 days + ten_days: 10 days + two_weeks: 2 weeks + three_weeks: 3 weeks + four_weeks: 4 weeks + one_month: 1 month + two_months: 2 months + three_months: 3 months submission_sources: api: API bulk: Bulk Send @@ -1501,6 +1520,25 @@ es: &es name_a_z: Nombre A-Z recently_used: Usado recientemente newest_first: Más reciente primero + none: Ninguno + default_expiration: Vencimiento predeterminado + specified_date: Fecha especificada + one_day: 1 día + two_days: 2 días + three_days: 3 días + four_days: 4 días + five_days: 5 días + six_days: 6 días + seven_days: 7 días + eight_days: 8 días + nine_days: 9 días + ten_days: 10 días + two_weeks: 2 semanas + three_weeks: 3 semanas + four_weeks: 4 semanas + one_month: 1 mes + two_months: 2 meses + three_months: 3 meses submission_sources: api: API bulk: Envío masivo @@ -2284,6 +2322,25 @@ it: &it name_a_z: Nome A-Z recently_used: Recentemente usato newest_first: Più recenti prima + none: Nessuno + default_expiration: Scadenza predefinita + specified_date: Data specificata + one_day: 1 giorno + two_days: 2 giorni + three_days: 3 giorni + four_days: 4 giorni + five_days: 5 giorni + six_days: 6 giorni + seven_days: 7 giorni + eight_days: 8 giorni + nine_days: 9 giorni + ten_days: 10 giorni + two_weeks: 2 settimane + three_weeks: 3 settimane + four_weeks: 4 settimane + one_month: 1 mese + two_months: 2 mesi + three_months: 3 mesi submission_sources: api: API bulk: Invio massivo @@ -3069,6 +3126,25 @@ fr: &fr name_a_z: Nom A-Z recently_used: Récemment utilisé newest_first: Le plus récent d'abord + none: Aucun + default_expiration: Expiration par défaut + specified_date: Date spécifiée + one_day: 1 jour + two_days: 2 jours + three_days: 3 jours + four_days: 4 jours + five_days: 5 jours + six_days: 6 jours + seven_days: 7 jours + eight_days: 8 jours + nine_days: 9 jours + ten_days: 10 jours + two_weeks: 2 semaines + three_weeks: 3 semaines + four_weeks: 4 semaines + one_month: 1 mois + two_months: 2 mois + three_months: 3 mois submission_sources: api: API bulk: Envoi en masse @@ -3853,6 +3929,25 @@ pt: &pt name_a_z: Nome A-Z recently_used: Recentemente usado newest_first: Mais recente primeiro + none: Nenhum + default_expiration: Expiração padrão + specified_date: Data especificada + one_day: 1 dia + two_days: 2 dias + three_days: 3 dias + four_days: 4 dias + five_days: 5 dias + six_days: 6 dias + seven_days: 7 dias + eight_days: 8 dias + nine_days: 9 dias + ten_days: 10 dias + two_weeks: 2 semanas + three_weeks: 3 semanas + four_weeks: 4 semanas + one_month: 1 mês + two_months: 2 meses + three_months: 3 meses submission_sources: api: API bulk: Envio em massa @@ -4638,6 +4733,25 @@ de: &de name_a_z: Name A-Z recently_used: Kürzlich verwendet newest_first: Neueste zuerst + none: Keine + default_expiration: Standardablauf + specified_date: Angegebenes Datum + one_day: 1 Tag + two_days: 2 Tage + three_days: 3 Tage + four_days: 4 Tage + five_days: 5 Tage + six_days: 6 Tage + seven_days: 7 Tage + eight_days: 8 Tage + nine_days: 9 Tage + ten_days: 10 Tage + two_weeks: 2 Wochen + three_weeks: 3 Wochen + four_weeks: 4 Wochen + one_month: 1 Monat + two_months: 2 Monate + three_months: 3 Monate submission_sources: api: API bulk: Massenversand diff --git a/lib/submissions.rb b/lib/submissions.rb index ddb4c3f8..ea59a83b 100644 --- a/lib/submissions.rb +++ b/lib/submissions.rb @@ -63,6 +63,7 @@ module Submissions submission = template.submissions.new(created_by_user: user, account_id: user.account_id, source:, + expire_at: params[:expire_at].presence || build_default_expire_at(template), template_submitters: template.submitters) submission.submitters.new(email: normalize_email(email), @@ -207,4 +208,17 @@ module Submissions Submissions::GenerateCombinedAttachment.call(submission.submitters.completed.order(:completed_at).last) end + + def build_default_expire_at(template) + default_expire_at_duration = template.preferences['default_expire_at_duration'].presence + default_expire_at = template.preferences['default_expire_at'].presence + + return if default_expire_at_duration.blank? + + if default_expire_at_duration == 'specified_date' && default_expire_at.present? + Time.zone.parse(default_expire_at) + elsif Template::EXPIRATION_DURATIONS[default_expire_at_duration] + Time.current.in_time_zone(template.account.timezone) + Template::EXPIRATION_DURATIONS[default_expire_at_duration] + end + end end diff --git a/lib/submissions/create_from_submitters.rb b/lib/submissions/create_from_submitters.rb index a0c274fa..bc9ee8d9 100644 --- a/lib/submissions/create_from_submitters.rb +++ b/lib/submissions/create_from_submitters.rb @@ -16,11 +16,12 @@ module Submissions set_submission_preferences = submission_preferences.slice('send_email', 'bcc_completed') set_submission_preferences['send_email'] = true if params['send_completed_email'] + expire_at = attrs[:expire_at] || Submissions.build_default_expire_at(template) submission = template.submissions.new(created_by_user: user, source:, account_id: user.account_id, preferences: set_submission_preferences, - expire_at: attrs[:expire_at], + expire_at:, template_submitters: [], submitters_order:) template_submitters = template.submitters.deep_dup