From a96c99d5112ba01df3a6c6850b5639e88911132c Mon Sep 17 00:00:00 2001
From: George Katsikas <giorgakis.katsikas@gmail.com>
Date: Wed, 9 Oct 2024 13:39:10 +0200
Subject: [PATCH] add assignment stage update mail command

fixes #340
---
 .../commands/send_assignment_stage_update.py  | 56 +++++++++++++++++++
 .../update_authors_assignment_stage.html      | 20 ++++---
 .../update_authors_assignment_stage.json      | 11 ++++
 3 files changed, 78 insertions(+), 9 deletions(-)
 create mode 100644 scipost_django/submissions/management/commands/send_assignment_stage_update.py
 create mode 100644 scipost_django/templates/email/authors/update_authors_assignment_stage.json

diff --git a/scipost_django/submissions/management/commands/send_assignment_stage_update.py b/scipost_django/submissions/management/commands/send_assignment_stage_update.py
new file mode 100644
index 000000000..1d523abc9
--- /dev/null
+++ b/scipost_django/submissions/management/commands/send_assignment_stage_update.py
@@ -0,0 +1,56 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.core.management.base import BaseCommand
+from django.utils import timezone
+
+from mails.utils import DirectMailUtil
+
+from ...models import Submission
+
+
+class Command(BaseCommand):
+    help = "Sends all email reminders needed for Submissions in the assignment stage"
+
+    def handle(self, *args, **options):
+        submission: Submission
+        for submission in Submission.objects.seeking_assignment():
+            now = timezone.now()
+            today = now.date()
+
+            # Skip if assignment deadline is not set
+            if submission.assignment_deadline is None:
+                continue
+
+            # If the date of passing preassignment checks is not set, set it to now
+            if submission.checks_cleared_date is None:
+                submission.checks_cleared_date = now
+                submission.save()
+
+            default_assignment_period_weeks = (
+                submission.submitted_to.assignment_period.days // 7
+            )
+
+            days_passed = (today - submission.checks_cleared_date.date()).days
+            weeks_passed = days_passed // 7
+
+            days_remaining = (submission.assignment_deadline - today).days
+            weeks_until_assignment_deadline = days_remaining // 7
+
+            # Send reminders after preassignment checks are cleared and only at 7-day intervals
+            if weeks_passed <= 0 or days_passed % 7 != 0:
+                continue
+
+            # Skip if just passed preassignment or just expired
+            if (weeks_passed == 0) or (weeks_until_assignment_deadline <= 0):
+                continue
+
+            mail = DirectMailUtil(
+                f"authors/update_authors_assignment_stage",
+                submission=submission,
+                weeks_until_assignment_deadline=weeks_until_assignment_deadline,
+                weeks_passed=weeks_passed,
+                default_assignment_period_weeks=default_assignment_period_weeks,
+            )
+            mail.send_mail()
diff --git a/scipost_django/templates/email/authors/update_authors_assignment_stage.html b/scipost_django/templates/email/authors/update_authors_assignment_stage.html
index b7e6cb5d2..c89a861e7 100644
--- a/scipost_django/templates/email/authors/update_authors_assignment_stage.html
+++ b/scipost_django/templates/email/authors/update_authors_assignment_stage.html
@@ -1,18 +1,18 @@
 <p>Dear {{ submission.submitted_by.profile.formal_name }},</p>
 <p>We would hereby like to give you an update on your recent SciPost submission,</p>
 <p>
-  {{ submission.title }}
+  <a href="https://{{ domain }}{% url 'submissions:submission' submission.preprint.identifier_w_vn_nr %}">{{ submission.title }}</a>,
   <br />
   by {{ submission.author_list }}.
 </p>
 
 <p>
-  Your Submission is in the <em>seeking assignment</em> stage, where unfortunaely no Editor-in-charge has yet volunteered to take charge of your Submission. At SciPost, Editorial Fellows choose which Submissions they wish to handle according to their interests, expertise and availability. While in this stage, your Submission will be visible to all Fellows, who may choose to take charge at any time. If this occurs, you will be immediately informed and the refereeing process will begin. Otherwise, we will keep searching for an Editor-in-charge and keep you informed of any new developments.
+  Your Submission is in the "seeking assignment" stage, where unfortunately no Editor-in-charge has yet volunteered to take charge of your Submission. At SciPost, Editorial Fellows choose which Submissions they wish to handle according to their interests, expertise and availability. While in this stage, your Submission will be visible to all Fellows, who may choose to take charge at any time. If this occurs, you will be immediately informed and the refereeing process will begin. Otherwise, we will keep searching for an Editor-in-charge and keep you informed of any new developments.
 </p>
 
 {% if weeks_passed == 1 and submission.qualification_set.exists %}
   <p>
-    Over the past week, your submission has been examined by {{ submission.qualification_set.all|length }} Fellow{{ submission.qualification_set.all|pluralize }}, of which {{ submission.qualification_set.qualified|length }} {{ submission.qualification_set.qualified|length_is:1|yesno:"is,are" }} sufficiently qualified to take charge.
+    Over the past week, your submission has been examined by {{ submission.qualification_set.all|length }} Fellow{{ submission.qualification_set.all|pluralize }}, of which {{ submission.qualification_set.qualified|length }} {{ submission.qualification_set.qualified|pluralize:"is,are" }} sufficiently qualified to take charge.
   </p>
 {% endif %}
 
@@ -29,7 +29,7 @@
     {% for offers in offers_by_type %}
       {% with offer=offers.list.0 %}
         <li>
-          {{ offers.list|length }} offers for {{ offer.condition }}: <a href="{% url 'submissions:accept_conditional_assignment_offer' pk=offer.id %}">accept first</a>
+          {{ offers.list|length }} offer{{ offers.list|pluralize }} for {{ offer.condition }}: <a href="https://{{ domain }}{% url 'submissions:accept_conditional_assignment_offer' submission.preprint.identifier_w_vn_nr offer.id %}">Accept</a> (login required, direct link without confirmation)
         </li>
       {% endwith %}
     {% endfor %}
@@ -38,13 +38,13 @@
 
   <p>
     Should you accept any such offer, the requested conditions will be applied, and the Fellow in question will immediately be notified and take charge of your Submission.
-    If you feel no offer is suitable, no further action is required from your side. Your Submission will then simply remain in the <em>seeking assignment</em> stage.
+    If you feel no offer is suitable, no further action is required from your side. Your Submission will then simply remain in the "seeking assignment" stage.
   </p>
 {% endif %}
 
 {% if submission_nearning_deadline %}
   <p>
-    We would like to inform you that the maximal duration of the assignment stage for submissions to {{ submission.submitted_to.name }} is {{ submission.submitted_to.assignment_period.days }} days. Since {{ weeks_passed }} week{{ weeks_passed|pluralize }} have already passed, we would like to further present you with the following options:
+    We would like to inform you that the maximal duration of the assignment stage for submissions to {{ submission.submitted_to.name }} is {{ default_assignment_period_weeks }} weeks. Since {{ weeks_passed }} week{{ weeks_passed|pluralize }} {{ weeks_passed|pluralize:"has,have" }} already passed, we would like to further present you with the following options:
     <ul>
 
       <li>
@@ -52,9 +52,11 @@
         Furthermore, when the deadline is reached, your submission will be returned to you, freeing you to submit it elsewhere.
       </li>
 
-      {% if weeks_until_assignment_deadline < submission.submitted_to.assignment_period.weeks %}
+      <!-- Deadline extension option, only if not already extended -->
+
+      {% if not submission.has_extended_assignment_deadline %}
         <li>
-          You may choose to have the <a href="">assignment stage deadline extended</a> by an additional {{ submission.submitted_to.assignment_period.days }} days. Note that this extension may only happen once.
+          You may choose to have the <a href="https://{{ domain }}{% url 'submissions:extend_assignment_deadline' submission.preprint.identifier_w_vn_nr %}">assignment stage deadline extended</a> by an additional {{ default_assignment_period_weeks }} weeks. Note that this extension may only happen once.
         </li>
       {% else %}
         <li>
@@ -64,7 +66,7 @@
       {% endif %}
 
       <li>
-        You may prematurely <a href="">withdraw your Submission</a> and seek an alternative venue. You can also do this at any time from your personal page, under the Submissions tab.
+        You may prematurely <a href="https://{{ domain }}{% url 'submissions:withdraw_manuscript' submission.preprint.identifier_w_vn_nr %}">withdraw your Submission</a> and seek an alternative venue. You can also do this at any time from your personal page, under the Submissions tab.
       </li>
 
     </ul>
diff --git a/scipost_django/templates/email/authors/update_authors_assignment_stage.json b/scipost_django/templates/email/authors/update_authors_assignment_stage.json
new file mode 100644
index 000000000..3a0913f87
--- /dev/null
+++ b/scipost_django/templates/email/authors/update_authors_assignment_stage.json
@@ -0,0 +1,11 @@
+{
+    "subject": "SciPost: Update on your submission seeking assignment",
+    "recipient_list": [
+        "submitted_by.user.email"
+    ],
+    "bcc": [
+        "submissions@"
+    ],
+    "from_name": "SciPost Editorial Admin",
+    "from_email": "submissions@"
+}
-- 
GitLab