SciPost Code Repository

Skip to content
Snippets Groups Projects
Commit b88597b3 authored by George Katsikas's avatar George Katsikas :goat:
Browse files

abstract editorial communication logic to model

parent 715ad941
No related branches found
No related tags found
No related merge requests found
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3" __license__ = "AGPL v3"
import itertools
ED_COMM_CHOICES = (
("EtoA", "Editor-in-charge to Author"), ED_COMM_PARTIES = (
("EtoR", "Editor-in-charge to Referee"), ("E", "Editor-in-charge"),
("EtoS", "Editor-in-charge to SciPost Editorial Administration"), ("A", "Author"),
("AtoE", "Author to Editor-in-charge"), ("R", "Referee"),
("RtoE", "Referee to Editor-in-charge"), ("S", "SciPost Editorial Administration"),
("StoE", "SciPost Editorial Administration to Editor-in-charge"), )
ED_COMM_CHOICES = tuple(
(f"{X}to{Y}", f"{x} to {y}")
for (X, x), (Y, y) in itertools.product(ED_COMM_PARTIES, repeat=2)
if X != Y
) )
REFEREE_QUALIFICATION = ( REFEREE_QUALIFICATION = (
......
...@@ -6,6 +6,8 @@ from django.db import models ...@@ -6,6 +6,8 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from common.utils.models import get_current_domain
from ..behaviors import SubmissionRelatedObjectMixin from ..behaviors import SubmissionRelatedObjectMixin
from ..constants import ED_COMM_CHOICES from ..constants import ED_COMM_CHOICES
from ..managers import EditorialCommunicationQuerySet from ..managers import EditorialCommunicationQuerySet
...@@ -51,3 +53,59 @@ class EditorialCommunication(SubmissionRelatedObjectMixin, models.Model): ...@@ -51,3 +53,59 @@ class EditorialCommunication(SubmissionRelatedObjectMixin, models.Model):
def get_absolute_url(self): def get_absolute_url(self):
"""Return the url of the related Submission detail page.""" """Return the url of the related Submission detail page."""
return self.submission.get_absolute_url() return self.submission.get_absolute_url()
def _resolve_contributor_from_letter(self, letter: str):
recipients: dict[str, "Contributor | None"] = {
"E": self.submission.editor_in_charge,
"A": self.submission.submitted_by,
"R": self.referee,
}
return recipients.get(letter)
def _resolve_contributor_name(self, letter: str):
if letter == "S":
return "SciPost Editorial Administration"
elif contributor := self._resolve_contributor_from_letter(letter):
return f"{contributor.profile_title} {contributor.user.last_name}"
return "Unknown"
def _resolve_contributor_email(self, letter: str):
if letter == "S":
domain = get_current_domain()
return f"editorial@{domain}"
elif contributor := self._resolve_contributor_from_letter(letter):
return contributor.user.email
return ""
@property
def author_letter(self):
return self.comtype[0]
@property
def recipient_letter(self):
return self.comtype[-1]
@property
def author(self):
return self._resolve_contributor_from_letter(self.author_letter)
@property
def recipient(self):
return self._resolve_contributor_from_letter(self.recipient_letter)
@property
def author_name(self):
return self._resolve_contributor_name(self.author_letter)
@property
def recipient_name(self):
return self._resolve_contributor_name(self.recipient_letter)
@property
def author_email(self):
return self._resolve_contributor_email(self.author_letter)
@property
def recipient_email(self):
return self._resolve_contributor_email(self.recipient_letter)
...@@ -15,6 +15,8 @@ from django.template import Context, Template ...@@ -15,6 +15,8 @@ from django.template import Context, Template
from common.utils.urls import absolute_reverse from common.utils.urls import absolute_reverse
from .constants import ( from .constants import (
ED_COMM_CHOICES,
ED_COMM_PARTIES,
STATUS_VETTED, STATUS_VETTED,
STATUS_UNCLEAR, STATUS_UNCLEAR,
STATUS_INCORRECT, STATUS_INCORRECT,
...@@ -725,15 +727,6 @@ class SubmissionUtils(BaseMailUtil): ...@@ -725,15 +727,6 @@ class SubmissionUtils(BaseMailUtil):
""" """
recipient_email = [] recipient_email = []
bcc_emails = [] bcc_emails = []
further_action_page = None
PARTIES = ["E", "A", "R", "S"]
# Allow only comtype to and from E(ditor)
valid_comtypes = [
f"{x}to{y}"
for x, y in itertools.product(PARTIES, repeat=2)
if "E" in [x, y] and x != y
]
communication: "EditorialCommunication | None" = getattr( communication: "EditorialCommunication | None" = getattr(
cls, "communication", None cls, "communication", None
...@@ -741,44 +734,23 @@ class SubmissionUtils(BaseMailUtil): ...@@ -741,44 +734,23 @@ class SubmissionUtils(BaseMailUtil):
if communication is None: if communication is None:
raise ValueError("No communication attribute found. Please `.load()` it.") raise ValueError("No communication attribute found. Please `.load()` it.")
valid_comtypes = [comtype[0] for comtype in ED_COMM_CHOICES]
if communication.comtype not in valid_comtypes: if communication.comtype not in valid_comtypes:
raise ValueError( raise ValueError(
f"Invalid comtype {communication.comtype}. " f"Invalid comtype {communication.comtype}. "
f"Valid comtypes are {valid_comtypes}." f"Valid comtypes are {valid_comtypes}."
) )
recipients: dict[str, "Contributor | None"] = { # BCC all non-edadmin communications to the Editorial Administrator
"E": communication.submission.editor_in_charge, if communication.recipient_letter != "S":
"A": communication.submission.submitted_by,
"R": communication.referee,
}
author, recipient = re.match(r"(\w)to(\w)", communication.comtype).groups()
# Use standard greeting for all communications except to Editorial Administrator
if recipient != "S":
recipient_contributor = recipients.get(recipient, None)
if recipient_contributor is None:
raise ValueError(
f"Recipient not found for comtype {communication.comtype}. Must be one of {recipients.keys()}"
)
recipient_email.append(recipient_contributor.user.email)
recipient_greeting = f"Dear {recipient_contributor.profile_title} {recipient_contributor.user.last_name}"
# BCC all non-edadmin communications to the Editorial Administrator
bcc_emails.append(f"submissions@{domain}") bcc_emails.append(f"submissions@{domain}")
else:
# Communication to Editorial Administrator doesn't have a specific recipient contributor
recipient_email.append(f"submissions@{domain}")
recipient_greeting = "Dear Editorial Administrators"
# BCC all editor-authored communications to the Editor-in-charge # BCC all editor-authored communications to the Editor-in-charge
if author == "E": if communication.author_letter == "E":
bcc_emails.append(communication.submission.editor_in_charge.user.email) bcc_emails.append(communication.author_email)
# Further action page for Editor and Editorial Administrator # Further action page for Editor and Editorial Administrator
if recipient in ["E", "S"]: # EtoS and _toE if communication.recipient_letter in ["E", "S"]: # _toS and _toE
editorial_page_url = absolute_reverse( editorial_page_url = absolute_reverse(
"submissions:editorial_page", "submissions:editorial_page",
args=[communication.submission.preprint.identifier_w_vn_nr], args=[communication.submission.preprint.identifier_w_vn_nr],
...@@ -787,24 +759,32 @@ class SubmissionUtils(BaseMailUtil): ...@@ -787,24 +759,32 @@ class SubmissionUtils(BaseMailUtil):
f"You can take follow-up actions from {editorial_page_url}." f"You can take follow-up actions from {editorial_page_url}."
) )
# Further action page for Author and Referee # Further action page for Author and Referee
elif recipient in ["R", "A"]: # EtoA and EtoR elif communication.recipient_letter in ["R", "A"]: # _toA and _toR
preprint_identifier = communication.submission.preprint.identifier_w_vn_nr preprint_identifier = communication.submission.preprint.identifier_w_vn_nr
communication_url = absolute_reverse( reverse_communication_url = absolute_reverse(
"submissions:communication", "submissions:communication",
args=[preprint_identifier, recipient + "toE"], args=[
preprint_identifier,
communication.recipient_letter + "to" + communication.author_letter,
# Reverse the communication direction, e.g. EtoA -> AtoE
],
) )
submission_page_url = absolute_reverse( submission_page_url = absolute_reverse(
"submissions:submission", "submissions:submission",
args=[preprint_identifier], args=[preprint_identifier],
) )
# Create a dictionary mapping author letters to author kinds
author_kinds = dict(zip(*zip(*ED_COMM_PARTIES)))
author_kind = author_kinds.get(communication.author_letter)
further_action = ( further_action = (
f"To reply to the Editor-in-charge, please visit {communication_url}. " f"To reply to the {author_kind}, please visit {reverse_communication_url}. "
"You can find all previous communications between you and the Editor-in-charge, as well as other communications tools, " f"You can find all previous communications between you and the {author_kind}, as well as other communications tools, "
f"on the submission page at {submission_page_url} (login needed)." f"on the submission page at {submission_page_url} (login needed)."
) )
email_text = ( email_text = (
f"{recipient_greeting},\n\n" f"Dear {communication.recipient_name},\n\n"
f"Please find here a communication ({communication.get_comtype_display()}) concerning Submission:\n\n" f"Please find here a communication ({communication.get_comtype_display()}) concerning Submission:\n\n"
f"{communication.submission.title}\nby {communication.submission.author_list}.\n" f"{communication.submission.title}\nby {communication.submission.author_list}.\n"
f"(https://{domain}/{communication.submission.get_absolute_url()})\n\n" f"(https://{domain}/{communication.submission.get_absolute_url()})\n\n"
...@@ -819,10 +799,10 @@ class SubmissionUtils(BaseMailUtil): ...@@ -819,10 +799,10 @@ class SubmissionUtils(BaseMailUtil):
) )
emailmessage = EmailMessage( emailmessage = EmailMessage(
"SciPost: communication (" + communication.get_comtype_display() + ")", f"SciPost: communication ({communication.get_comtype_display()})",
email_text, email_text,
f"SciPost Editorial Admin <submissions@{domain}>", f"SciPost Editorial Admin <submissions@{domain}>",
recipient_email, [communication.recipient_email],
bcc_emails, bcc_emails,
reply_to=[f"submissions@{domain}"], reply_to=[f"submissions@{domain}"],
) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment