diff --git a/app/controllers/submissions_resend_email_controller.rb b/app/controllers/submissions_resend_email_controller.rb
new file mode 100644
index 00000000..82d10797
--- /dev/null
+++ b/app/controllers/submissions_resend_email_controller.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+class SubmissionsResendEmailController < ApplicationController
+ load_and_authorize_resource :submission
+
+ before_action do
+ authorize!(:manage, :resend_all)
+ end
+
+ def create
+ submitters = @submission.submitters.reject(&:completed_at?).select { |s| s.email.present? && !s.declined_at? }
+
+ if Docuseal.multitenant?
+ recent_submitter_ids =
+ SubmissionEvent.where(submitter_id: submitters.map(&:id),
+ event_type: 'send_email',
+ created_at: 10.hours.ago..Time.current).pluck(:submitter_id).to_set
+
+ submitters = submitters.reject { |s| recent_submitter_ids.include?(s.id) }
+ end
+
+ submitters.each do |submitter|
+ SendSubmitterInvitationEmailJob.perform_async('submitter_id' => submitter.id)
+
+ submitter.sent_at ||= Time.current
+ submitter.save!
+ end
+
+ notice =
+ if submitters.empty?
+ I18n.t('email_has_been_sent_already')
+ else
+ I18n.t('emails_have_been_sent_to_n_recipients', count: submitters.size)
+ end
+
+ redirect_back(fallback_location: submission_path(@submission), notice:)
+ end
+end
diff --git a/app/views/submissions/show.html.erb b/app/views/submissions/show.html.erb
index 83187f47..7922949c 100644
--- a/app/views/submissions/show.html.erb
+++ b/app/views/submissions/show.html.erb
@@ -30,6 +30,12 @@
<%= t('event_log') %>
<% end %>
<% end %>
+ <% if signed_in? && !is_all_completed && can?(:manage, :resend_all) && @submission.submitters.to_a.size > 3 && !@submission.archived_at? && !@submission.template&.archived_at? && !@submission.expired? && can?(:update, @submission) %>
+ <% pending_submitters_count = @submission.submitters.to_a.count { |s| !s.completed_at? && s.email.present? && !s.declined_at? } %>
+ <% if pending_submitters_count.positive? %>
+ <%= button_to button_title(title: t('re_send_emails'), title_class: 'hidden md:inline', disabled_with: t('sending'), icon: svg_icon('mail_forward', class: 'w-6 h-6')), submission_resend_email_index_path(@submission), class: 'white-button', data: { turbo_confirm: t('are_you_sure_you_want_to_re_send_email_to_n_recipients', count: pending_submitters_count) } %>
+ <% end %>
+ <% end %>
<% if @submission.submitters.to_a.any?(&:completed_at?) %>
<% if is_all_completed || !is_combined_enabled %>
diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml
index 055aa022..ebba6d4f 100644
--- a/config/locales/i18n.yml
+++ b/config/locales/i18n.yml
@@ -658,6 +658,9 @@ en: &en
create_a_new_template_document_form_or_submit_the_existing_one_html:
Create a new template document form or
submit the existing one
send_email_copy_with_completed_documents_to_a_specified_bcc_address: Send email copy with completed documents to a specified BCC address.
re_send_email: Re-send Email
+ re_send_emails: Re-send Emails
+ are_you_sure_you_want_to_re_send_email_to_n_recipients: Are you sure you want to re-send the invitation email to %{count} recipients?
+ emails_have_been_sent_to_n_recipients: Emails have been sent to %{count} recipients.
send_email: Send Email
copy_share_link: Copy Share Link
copied_to_clipboard: Copied to Clipboard
@@ -1708,6 +1711,9 @@ es: &es
create_a_new_template_document_form_or_submit_the_existing_one_html:
Crear una nueva plantilla de documento o
enviar el existente
send_email_copy_with_completed_documents_to_a_specified_bcc_address: Enviar una copia del correo electrónico con los documentos completados a una dirección BCC especificada.
re_send_email: Reenviar correo electrónico
+ re_send_emails: Reenviar emails
+ are_you_sure_you_want_to_re_send_email_to_n_recipients: ¿Estás seguro de que quieres reenviar el correo de invitación a %{count} destinatarios?
+ emails_have_been_sent_to_n_recipients: Los correos electrónicos han sido enviados a %{count} destinatarios.
send_email: Enviar correo electrónico
copy_share_link: Copiar enlace de compartir
copied_to_clipboard: Copiado al portapapeles
@@ -2755,6 +2761,9 @@ it: &it
create_a_new_template_document_form_or_submit_the_existing_one_html:
Crea un nuovo modello di documento o
invia quello esistente
send_email_copy_with_completed_documents_to_a_specified_bcc_address: Invia una copia dell'email con i documenti completati a un indirizzo BCC specificato.
re_send_email: Invia di nuovo l'email
+ re_send_emails: Reinvia email
+ are_you_sure_you_want_to_re_send_email_to_n_recipients: Sei sicuro di voler inviare di nuovo l'email di invito a %{count} destinatari?
+ emails_have_been_sent_to_n_recipients: Le email sono state inviate a %{count} destinatari.
send_email: Invia email
copy_share_link: Copia link di condivisione
copied_to_clipboard: Copiato negli appunti
@@ -3802,6 +3811,9 @@ fr: &fr
create_a_new_template_document_form_or_submit_the_existing_one_html:
Créez un nouveau modèle de document ou
soumettez l’existant
send_email_copy_with_completed_documents_to_a_specified_bcc_address: Envoyer une copie e‑mail avec les documents complétés à une adresse Cci spécifiée.
re_send_email: Renvoyer l’e‑mail
+ re_send_emails: Renvoyer e‑mails
+ are_you_sure_you_want_to_re_send_email_to_n_recipients: Êtes‑vous sûr de vouloir renvoyer l’e‑mail d’invitation à %{count} destinataires ?
+ emails_have_been_sent_to_n_recipients: Les e‑mails ont été envoyés à %{count} destinataires.
send_email: Envoyer l’e‑mail
copy_share_link: Copier le lien de partage
copied_to_clipboard: Copié dans le presse‑papiers
@@ -4846,6 +4858,9 @@ pt: &pt
create_a_new_template_document_form_or_submit_the_existing_one_html: '
Criar um novo modelo de documento ou
submeter o existente'
send_email_copy_with_completed_documents_to_a_specified_bcc_address: Envie uma cópia do e-mail com documentos concluídos para um endereço BCC especificado.
re_send_email: Reenviar e-mail
+ re_send_emails: Reenviar e-mails
+ are_you_sure_you_want_to_re_send_email_to_n_recipients: Tem certeza de que deseja reenviar o e-mail de convite para %{count} destinatários?
+ emails_have_been_sent_to_n_recipients: Os e-mails foram enviados para %{count} destinatários.
send_email: Enviar e-mail
copy_share_link: Copiar link de compartilhamento
copied_to_clipboard: Copiado para a área de transferência
@@ -5893,6 +5908,9 @@ de: &de
create_a_new_template_document_form_or_submit_the_existing_one_html:
Neue Vorlage erstellen oder
bestehende einreichen
send_email_copy_with_completed_documents_to_a_specified_bcc_address: Senden Sie eine E-Mail-Kopie mit abgeschlossenen Dokumenten an eine angegebene BCC-Adresse.
re_send_email: E-Mail erneut senden
+ re_send_emails: E-Mails senden
+ are_you_sure_you_want_to_re_send_email_to_n_recipients: Sind Sie sicher, dass Sie die Einladungs-E-Mail erneut an %{count} Empfänger senden möchten?
+ emails_have_been_sent_to_n_recipients: Die E-Mails wurden an %{count} Empfänger gesendet.
send_email: E-Mail senden
copy_share_link: Freigabelink kopieren
copied_to_clipboard: In die Zwischenablage kopiert
@@ -7345,6 +7363,9 @@ nl: &nl
create_a_new_template_document_form_or_submit_the_existing_one_html:
Maak een nieuw sjabloon voor een documentformulier of
dien het bestaande in
send_email_copy_with_completed_documents_to_a_specified_bcc_address: Stuur een e-mailkopie met voltooide documenten naar een opgegeven BCC-adres.
re_send_email: E-mail opnieuw verzenden
+ re_send_emails: E-mails verzenden
+ are_you_sure_you_want_to_re_send_email_to_n_recipients: Weet je zeker dat je de uitnodigings-e-mail opnieuw wilt verzenden naar %{count} ontvangers?
+ emails_have_been_sent_to_n_recipients: De e-mails zijn verzonden naar %{count} ontvangers.
send_email: E-mail verzenden
copy_share_link: Deellink kopiëren
copied_to_clipboard: Gekopieerd naar klembord
diff --git a/config/routes.rb b/config/routes.rb
index 3ae4c1b3..b2b33752 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -72,6 +72,7 @@ Rails.application.routes.draw do
resources :unarchive, only: %i[create], controller: 'submissions_unarchive'
resources :events, only: %i[index], controller: 'submission_events'
resources :download, only: %i[index], controller: 'submissions_download'
+ resources :resend_email, only: %i[create], controller: 'submissions_resend_email'
end
resources :submitters, only: %i[edit update]
resources :console_redirect, only: %i[index]