-
Andrei Cioromila authorededd45dce
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
const config = require('config')
const { get, chain } = require('lodash')
const { services } = require('pubsweet-component-helper-service')
const { getEmailCopy } = require('./emailCopy')
const unsubscribeSlug = config.get('unsubscribe.url')
const { name: journalName, staffEmail } = config.get('journal')
module.exports = {
sendReviewersEmail: async ({ email, baseUrl, reviewers }) => {
reviewers.forEach(reviewer => {
email.toUser = {
email: reviewer.email,
name: `${reviewer.lastName}`,
}
email.content.unsubscribeLink = services.createUrl(
baseUrl,
unsubscribeSlug,
{
id: reviewer.id,
token: reviewer.accessTokens.unsubscribe,
},
)
const emailBodyProps = {
paragraph: reviewer.paragraph,
hasLink: reviewer.hasLink,
hasIntro: reviewer.hasIntro,
hasSignature: reviewer.hasSignature,
}
const { html, text } = email.getNotificationBody({ emailBodyProps })
email.sendEmail({ html, text })
})
},
getSubmittedReviewers: async ({
UserModel,
titleText,
fragmentHelper,
recommendation,
}) => {
const emailType =
recommendation === 'publish'
? 'submitted-reviewers-after-publish'
: 'submitted-reviewers-after-reject'
const reviewers = (await fragmentHelper.getReviewers({
UserModel,
type: 'submitted',
})).map(rev => ({
...rev,
emailType,
...getEmailCopy({
emailType,
titleText,
}),
}))
return reviewers
},
getNoResponseReviewers: async ({ fragmentHelper, UserModel, titleText }) => {
const acceptedReviewers = (await fragmentHelper.getReviewers({
UserModel,
type: 'accepted',
})).map(rev => ({
...rev,
...getEmailCopy({
emailType: 'accepted-reviewers-after-recommendation',
titleText,
}),
}))
const pendingReviewers = (await fragmentHelper.getReviewers({
UserModel,
type: 'pending',
})).map(rev => ({
...rev,
...getEmailCopy({
emailType: 'pending-reviewers-after-recommendation',
titleText,
}),
}))
const reviewers = [...acceptedReviewers, ...pendingReviewers]
return reviewers
},
updateEmailContentForReviewers: ({
email,
customId,
signatureName,
recommendation,
}) => {
const subject =
recommendation === 'publish'
? 'A manuscript you reviewed has been accepted'
: 'A manuscript you reviewed has been rejected'
email.content.subject = `${customId}: ${subject}`
email.content.signatureName = signatureName
email.content.signatureJournal = journalName
email.fromEmail = `${signatureName} <$staffEmail>`
return email
},
sendHandlingEditorEmail: ({
email,
comments,
emailType,
titleText,
targetUserName,
}) => {
const { html, text } = email.getNotificationBody({
emailBodyProps: getEmailCopy({
emailType,
titleText,
comments,
targetUserName,
}),
})
email.sendEmail({ html, text })
},
updateEmailContentForHE: ({
email,
baseUrl,
eicName,
customId,
heLastName,
handlingEditor,
recommendation,
recommendationType,
}) => {
// TODO: this should probably be split in two functions, one for each type
email.fromEmail = `${eicName} <${staffEmail}>`
if (recommendationType === 'review') {
email.content.subject = `${customId}: A review has been submitted`
} else {
switch (recommendation) {
case 'return-to-handling-editor':
email.content.subject = `${customId}: Editorial decision returned with comments`
break
case 'publish':
case 'reject':
email.content.subject = `${customId}: Editorial decision confirmed`
break
default:
throw new Error(`Undefined recommendation: ${recommendation}`)
}
}
email.toUser = {
email: handlingEditor.email,
name: heLastName,
}
email.content.unsubscribeLink = services.createUrl(
baseUrl,
unsubscribeSlug,
{
id: handlingEditor.id,
token: handlingEditor.accessTokens.unsubscribe,
},
)
email.content.signatureName = eicName
delete email.content.signatureJournal
return email
},
getEmailTypeByRecommendationForHE: ({
recommendation,
recommendationType,
}) => {
let emailType
if (recommendationType === 'review') {
emailType = 'he-review-submitted'
} else {
switch (recommendation) {
case 'return-to-handling-editor':
emailType = 'he-manuscript-return-with-comments'
break
case 'publish':
emailType = 'he-manuscript-published'
break
case 'reject':
emailType = 'he-manuscript-rejected'
break
default:
throw new Error(`undefined recommendation: ${recommendation} `)
}
}
return emailType
},
getEiCCommentsForHE: ({ newRecommendation }) => {
const eicComments = chain(newRecommendation)
.get('comments')
.find(comm => !comm.public)
.get('content')
.value()
return eicComments
},
sendEiCsEmail: async ({
email,
customId,
titleText,
userHelper,
targetUserName,
recommendation: { recommendation, comments: recComments = [] },
}) => {
let emailType
email.fromEmail = `${journalName} <${staffEmail}>`
switch (recommendation) {
case 'minor':
case 'major':
emailType = 'eic-request-revision-from-he'
email.content.subject = `${customId}: Revision requested`
break
case 'publish':
emailType = 'eic-recommend-to-publish-from-he'
email.content.subject = `${customId}: Recommendation to publish`
break
case 'reject':
emailType = 'eic-recommend-to-reject-from-he'
email.content.subject = `${customId}: Recommendation to reject`
break
default:
throw new Error(`undefined recommendation: ${recommendation} `)
}
delete email.content.signatureJournal
const privateNote = recComments.find(comm => !comm.public)
const content = get(privateNote, 'content')
const comments = content
? `The editor provided the following comments: "${content}"`
: ''
const editors = (await userHelper.getEditorsInChief()).map(eic => ({
...eic,
...getEmailCopy({
comments,
emailType,
titleText,
targetUserName,
}),
}))
editors.forEach(eic => {
email.toUser = {
email: eic.email,
name: `${eic.firstName} ${eic.lastName}`,
}
const { html, text } = email.getNotificationBody({
emailBodyProps: {
paragraph: eic.paragraph,
hasLink: eic.hasLink,
hasIntro: eic.hasIntro,
hasSignature: eic.hasSignature,
},
})
email.sendEmail({ html, text })
})
},
sendAuthorsEmail: async ({ email, authors, baseUrl }) => {
authors.forEach(author => {
email.toUser = {
email: author.email,
name: `${author.lastName}`,
}
email.content.unsubscribeLink = services.createUrl(
baseUrl,
unsubscribeSlug,
{
id: author.id,
token: author.accessTokens.unsubscribe,
},
)
const { html, text } = email.getNotificationBody({
emailBodyProps: {
paragraph: author.paragraph,
hasLink: author.hasLink,
hasIntro: author.hasIntro,
hasSignature: author.hasSignature,
},
})
email.sendEmail({ html, text })
})
},
getSubmittingAuthor: ({
title,
journalName,
authorNoteText,
submittingAuthor,
}) => {
const author = {
...submittingAuthor,
...getEmailCopy({
emailType: 'author-request-to-revision',
titleText: `your submission "${title}" to ${journalName}`,
comments: authorNoteText,
}),
}
return author
},
getPrivateNoteTextForAuthor: ({ newRecommendation }) => {
const authorNote = newRecommendation.comments.find(comm => comm.public)
const content = get(authorNote, 'content')
const authorNoteText = content ? `Reason & Details: "${content}"` : ''
return authorNoteText
},
updateEmailContentForSA: ({ email, customId, signatureName }) => {
email.fromEmail = `${signatureName} <${staffEmail}>`
email.content.subject = `${customId}: Revision requested`
email.content.signatureName = signatureName
email.content.signatureJournal = journalName
return email
},
getHEComments: ({ heRecommendation }) => {
const heComments = get(heRecommendation, 'comments', [])
if (heComments.length === 0) return
const publicComment = heComments.find(comm => comm.public)
const content = get(publicComment, 'content')
if (!content) {
throw new Error('a public comment cannot be without content')
}
const comments = `Please find our editorial comments below<br/>: "${content}"`
return comments
},
getAllAuthors: ({ title, comments, emailType, fragmentAuthors }) => {
const authors = fragmentAuthors.map(author => ({
...author,
...getEmailCopy({
comments,
emailType,
titleText: `your manuscript titled "${title}"`,
}),
}))
return authors
},
sendSubmittingAuthorEmail: ({ email, author, baseUrl }) => {
email.toUser = {
email: author.email,
name: `${author.lastName}`,
}
email.content.unsubscribeLink = services.createUrl(
baseUrl,
unsubscribeSlug,
{
id: author.id,
token: author.accessTokens.unsubscribe,
},
)
const { html, text } = email.getNotificationBody({
emailBodyProps: {
paragraph: author.paragraph,
hasLink: author.hasLink,
hasIntro: author.hasIntro,
hasSignature: author.hasSignature,
},
})
email.sendEmail({ html, text })
},
updateEmailContentForAllAuthors: ({
email,
recommendation,
customId,
eicName,
}) => {
email.fromEmail = `${eicName} <${staffEmail}>`
switch (recommendation) {
case 'publish':
email.content.subject = `${customId}: Manuscript accepted`
break
case 'reject':
email.content.subject = `${customId}: Manuscript rejected`
break
default:
throw new Error(`Undefined recommendation: ${recommendation}`)
}
email.content.signatureJournal = journalName
return email
},
getEmailTypeByRecommendationForAuthors: ({
recommendation,
hasPeerReview,
}) => {
let emailType
switch (recommendation) {
case 'publish':
emailType = 'author-manuscript-published'
break
case 'reject':
emailType = hasPeerReview
? 'author-manuscript-rejected'
: 'authors-manuscript-rejected-before-review'
break
default:
throw new Error(`Undefined recommendation: ${recommendation}`)
}
return emailType
},
sendEQAEmail: ({
email,
eicName,
baseUrl,
titleText,
collection,
subjectBaseText,
}) => {
let emailType
switch (collection.status) {
case 'accepted':
emailType = 'eqa-manuscript-published'
email.content.subject = `${subjectBaseText} decision finalized`
break
case 'inQA':
emailType = 'eqa-manuscript-request-for-approval'
email.content.subject = `${subjectBaseText} Request for EQA Approval`
email.content.ctaLink = services.createUrl(
baseUrl,
config.get('eqa-decision.url'),
{
collectionId: collection.id,
customId: collection.customId,
token: collection.technicalChecks.token,
},
)
email.content.ctaText = 'MAKE DECISION'
break
default:
throw new Error(
`Cannot send EQA email when collection status is ${
collection.status
} `,
)
}
email.toUser = {
email: editorialAssistantEmail,
name: 'Editorial Assistant',
}
email.content.unsubscribeLink = baseUrl
email.content.signatureName = eicName
const { html, text } = email.getNotificationBody({
emailBodyProps: getEmailCopy({
eicName,
titleText,
emailType,
customId: collection.customId,
}),
})
email.sendEmail({ html, text })
},
}