diff --git a/packages/component-helper-service/src/Helper.js b/packages/component-helper-service/src/Helper.js index 0037b50c55ed4e8f5af9baccf34702df12b77731..b47dc41778f2baec3e50de9a08d72f1b5b4ffc4b 100644 --- a/packages/component-helper-service/src/Helper.js +++ b/packages/component-helper-service/src/Helper.js @@ -1,4 +1,4 @@ -const Email = require('./services/Email') +const Email = require('./services/email/Email') const Collection = require('./services/Collection') const Fragment = require('./services/Fragment') const services = require('./services/services') diff --git a/packages/component-helper-service/src/services/Email.js b/packages/component-helper-service/src/services/email/Email.1.js similarity index 88% rename from packages/component-helper-service/src/services/Email.js rename to packages/component-helper-service/src/services/email/Email.1.js index 8a6c29954fa300bbe3d76b5be587098c19c0679b..22d203fc1411f3aeda9136bd60ad52f7b1a4e663 100644 --- a/packages/component-helper-service/src/services/Email.js +++ b/packages/component-helper-service/src/services/email/Email.1.js @@ -1,11 +1,8 @@ const Fragment = require('./Fragment') const User = require('./User') -const services = require('./services') const get = require('lodash/get') const config = require('config') -const mailService = require('pubsweet-component-mail-template-service') - -const unsubscribeSlug = config.get('unsubscribe.url') +const mailService = require('pubsweet-component-mail-service') const manuscriptTypes = config.get('manuscript-types') @@ -163,7 +160,7 @@ class Email { baseUrl, UserModel, collection, - parsedFragment: { heRecommendation, id: fragmentId, title, newComments }, + parsedFragment: { heRecommendation, id, title, newComments }, authors: { submittingAuthor: { id: submittingAuthorId, @@ -177,20 +174,11 @@ class Email { if (requestToRevision) comments = newComments const authorNote = comments.find(comm => comm.public) const content = get(authorNote, 'content') - const notes = content ? `Reason & Details: "${content}"` : '' - - let emailType, subject - if (requestToRevision) { - emailType = 'author-request-to-revision' - subject = `${collection.customId}: Manuscript Recommendation` - } else if (publish) { - emailType = 'author-manuscript-published' - subject = `${collection.customId}: Manuscript Published` - } else { - emailType = 'author-manuscript-rejected' - subject = `${collection.customId}: Manuscript Rejected` - } - + const authorNoteText = content ? `Reason & Details: "${content}"` : '' + let emailType = requestToRevision + ? 'author-request-to-revision' + : 'author-manuscript-rejected' + if (publish) emailType = 'author-manuscript-published' let toAuthors = null if (emailType === 'author-request-to-revision') { toAuthors = [ @@ -201,7 +189,7 @@ class Email { }, ] } else { - const fragment = await FragmentModel.find(fragmentId) + const fragment = await FragmentModel.find(id) const userHelper = new User({ UserModel }) const activeAuthors = await userHelper.getActiveAuthors(fragment.authors) @@ -211,39 +199,23 @@ class Email { name: `${author.firstName} ${author.lastName}`, })) } - toAuthors.forEach(toAuthor => { mailService.sendNotificationEmail({ emailType, + toId: toAuthor.id, toEmail: toAuthor.email, - notes, - subject, - hasLink: false, - manuscriptTitleText: `the manuscript titled "${title}" by ${firstName} ${lastName}`, - replacements: { - signatureName: get(collection, 'handlingEditor.name'), - toUserName: toAuthor.name, - beforeAnchor: 'Please visit the', - afterAnchor: 'to see the full review', - detailsUrl: services.createUrl( - baseUrl, - `/projects/${collection.id}/versions/${fragmentId}/details`, - ), - unsubscribeLink: services.createUrl(baseUrl, unsubscribeSlug, { - id: toAuthor.id, - }), + meta: { + handlingEditorName: get(collection, 'handlingEditor.name'), + baseUrl, + collection, + authorNoteText, + fragment: { + id, + title, + authorName: toAuthor.name, + submittingAuthorName: `${firstName} ${lastName}`, + }, }, - // meta: { - // handlingEditorName: get(collection, 'handlingEditor.name'), - // baseUrl, - // collection, - // fragment: { - // id, - // title, - // authorName: toAuthor.name, - // submittingAuthorName: `${firstName} ${lastName}`, - // }, - // }, }) }) } diff --git a/packages/component-helper-service/src/services/email/Email.js b/packages/component-helper-service/src/services/email/Email.js new file mode 100644 index 0000000000000000000000000000000000000000..9205f49572a627d58ece8387e39e422acd0221fb --- /dev/null +++ b/packages/component-helper-service/src/services/email/Email.js @@ -0,0 +1,215 @@ +const config = require('config') +const helpers = require('./helpers') +const SendEmail = require('@pubsweet/component-send-email') +// const mailService = require('pubsweet-component-mail-template-service') + +class Email { + constructor({ + type = 'system', + toUser = { + id: '', + email: '', + name: '', + }, + content = { + subject: '', + titleText: '', + signatureName: '', + comments: '', + detailsLink: '', + sourceUserName: '', + unsubscribeLink: '', + timestamp: '', + }, + }) { + this.type = type + this.toUser = toUser + this.content = content + } + + set _toUser(newToUser) { + this.toUser = newToUser + } + + set _subject(newSubject) { + this.subject = newSubject + } + + set _content(newContent) { + this.content = newContent + } + getBody({ emailType }) { + const replacements = { + signatureName: this.content.signatureName, + toUserName: '', + beforeAnchor: 'Please visit the', + afterAnchor: 'to see the full review', + detailsLink: this.content.detailsLink, + unsubscribeLink: this.content.unsubscribeLink, + } + switch (emailType) { + case 'unassign-reviewer': + replacements.paragraph = `You are no longer needed to review ${ + this.titleText + }. If you have comments on this manuscript you believe the Editor should + see, please email them to ${config.get( + 'mailer.from', + )} as soon as possible. Thank you for your + time and I hope you will consider reviewing for Hindawi again.` + break + case 'review-submitted': + replacements.paragraph = `We are pleased to inform you that Dr. ${ + this.sourceUserName + } has submitted a review for ${this.titleText}.` + break + case 'reviewer-agreed': + // subject = `${meta.collection.customId}: Manuscript Reviews` + replacements.paragraph = `We are pleased to inform you that Dr. ${ + this.sourceUserName + } has agreed to review ${this.titleText}. <br/> + You should receive the report by Dr. ${ + this.sourceUserName + } before ${helpers.getExpectedDate(this.content.timestamp, 14)}.` + replacements.beforeAnchor = + 'If you have any queries, or would like to send a reminder if you no report has been submitted, then please visit the' + break + case 'reviewer-declined': + // subject = `${meta.collection.customId}: Manuscript Reviews` + replacements.paragraph = `We regret to inform you that Dr. ${ + this.sourceUserName + } has declined to review ${this.titleText}.` + replacements.afterAnchor = + 'to see if you need to invite any additional reviewers in order to reach a decision on the manuscript' + break + case 'reviewer-thank-you': + // subject = `${meta.collection.customId}: Manuscript Review` + replacements.paragraph = `Thank you for agreeing to review ${ + this.titleText + }.` + replacements.beforeAnchor = + 'You can view the full PDF file of the manuscript and post your review report using the following URL:' + replacements.afterAnchor = '' + break + case 'agreed-reviewers-after-he-recommendation': + replacements.hasLink = false + replacements.paragraph = `I appreciate any time you may have spent reviewing ${ + this.titleText + }. However, an editorial decision has been made and the review of this manuscript is now complete. I apologize for any inconvenience. <br/> + If you have comments on this manuscript you believe the Editor should see, please email them to Hindawi as soon as possible. <br/> + Thank you for your interest and I hope you will consider reviewing for Hindawi again.` + break + case 'pending-reviewers-after-he-recommendation': + replacements.hasLink = false + + replacements.paragraph = `An editorial decision has been made regarding ${ + this.titleText + }. So, you do not need to proceed with the review of this manuscript. <br/><br/> + If you have comments on this manuscript you believe the Editor should see, please email them to Hindawi as soon as possible.` + break + case 'eic-recommendation': + // subject = `${meta.collection.customId}: Manuscript Recommendation` + replacements.beforeAnchor = + 'For more information about what is required, please visit the ' + break + case 'author-request-to-revision': + replacements.paragraph = `In order for ${ + this.titleText + } to proceed to publication, there needs to be a revision. <br/><br/> + ${this.content.comments}<br/><br/>` + replacements.beforeAnchor = + 'For more information about what is required, please visit the ' + break + case 'author-manuscript-rejected': + replacements.paragraph = `I am sorry to inform you that ${ + this.titleText + } has been rejected for publication. <br/><br/> + ${this.content.comments}<br/><br/>` + replacements.hasLink = false + break + case 'author-manuscript-published': + replacements.paragraph = `I am delighted to inform you that ${ + this.titleText + } has passed through the review process and will be published in Hindawi.<br/><br/> + ${this.content.comments}<br/><br/> + Thanks again for choosing to publish with us.` + replacements.hasLink = false + break + case 'he-manuscript-rejected': + // subject = meta.emailSubject + replacements.hasLink = false + replacements.paragraph = `Thank you for your recommendation to reject ${ + this.titleText + } based on the reviews you received.<br/><br/> + I can confirm this article has now been rejected.` + break + case 'he-manuscript-published': + // subject = meta.emailSubject + replacements.hasLink = false + replacements.paragraph = `Thank you for your recommendation to publish the manuscript titled ${ + this.titleText + } based on the reviews you received.<br/><br/> + I can confirm this article will now go through to publication.` + break + case 'he-manuscript-return-with-comments': + // subject = meta.emailSubject + replacements.hasLink = false + replacements.paragraph = `Thank you for your recommendation for ${ + this.titleText + } based on the reviews you received.<br/><br/> + ${this.content.comments}<br/><br/>` + break + case 'submitting-reviewers-after-decision': + replacements.hasLink = false + replacements.paragraph = `Thank you for your review on ${ + this.titleText + }. After taking into account the reviews and the recommendation of the Handling Editor, I can confirm this article ${ + this.content.comments + }.<br/><br/> + If you have any queries about this decision, then please email them to Hindawi as soon as possible.` + break + case 'new-version-submitted': + replacements.paragraph = `A new version of ${ + this.titleText + } has been submitted.` + replacements.beforeAnchor = + 'Previous reviewers have been automatically invited to review the manuscript again. Please visit the' + replacements.afterAnchor = + 'to see the latest version and any other actions you may need to take' + break + case 'submitting-reviewers-after-revision': + replacements.paragraph = `A new version of ${ + this.titleText + } has been submitted.` + replacements.beforeAnchor = `As you have reviewed the previous version of this manuscript, I would be grateful if you can review this revised version and submit a review report by ${helpers.getExpectedDate( + this.content.timestamp, + 14, + )}. You can download the PDF of the revised version and submit your new review from the following URL:` + break + default: + throw new Error(`undefined email type: ${emailType}`) + } + + return { + html: helpers.getNotificationBody('notification', replacements), + text: `${replacements.intro} ${replacements.paragraph} ${ + replacements.beforeAnchor + } ${replacements.detailsUrl} ${replacements.afterAnchor} ${ + replacements.signatureName + }`, + } + } + + sendEmail({ text, html }) { + const mailData = { + from: config.get('mailer.from'), + to: this.toUser.email, + subject: this.content.subject, + text, + html, + } + + SendEmail.send(mailData) + } +} + +module.exports = Email diff --git a/packages/component-helper-service/src/services/email/helpers.js b/packages/component-helper-service/src/services/email/helpers.js new file mode 100644 index 0000000000000000000000000000000000000000..142112a83800d1388fe73870a1d208dedb0e9d1e --- /dev/null +++ b/packages/component-helper-service/src/services/email/helpers.js @@ -0,0 +1,125 @@ +const querystring = require('querystring') +const fs = require('fs') +const handlebars = require('handlebars') + +const createUrl = (baseUrl, slug, queryParams = null) => + !queryParams + ? `${baseUrl}${slug}` + : `${baseUrl}${slug}?${querystring.encode(queryParams)}` + +const getEmailBody = (emailType, replacements) => { + handlePartial('header', replacements) + handlePartial('footer', replacements) + handlePartial('mainButton', replacements) + handlePartial('mainBody', replacements) + + return getMainTemplate(emailType, replacements) +} + +const getNotificationBody = (emailType, replacements) => { + handlePartial('notificationHeader', replacements) + handlePartial('footer', replacements) + handlePartial('signature', replacements) + if (replacements.hasLink) handlePartial('manuscriptDetailsLink', replacements) + handlePartial('notificationBody', replacements) + + return getMainTemplate(emailType, replacements) +} + +const getInvitationBody = (emailType, replacements) => { + handlePartial('invitationHeader', replacements) + handlePartial('footer', replacements) + handlePartial('invitationUpperContent', replacements) + handlePartial('invitationButtons', replacements) + handlePartial('manuscriptData', replacements) + handlePartial('signature', replacements) + handlePartial('invitationLowerContent', replacements) + + return getMainTemplate(emailType, replacements) +} + +const getBody = (emailType, replacements) => { + const simplePartials = ['header', 'footer', 'mainButton', 'mainBody'] + const notificationPartials = [ + 'notificationHeader', + 'footer', + 'signature', + 'manuscriptDetailsLink', + 'notificationBody', + ] + const invitationPartials = [ + 'invitationHeader', + 'footer', + 'invitationUpperContent', + 'invitationButtons', + 'manuscriptData', + 'signature', + 'invitationLowerContent', + ] + + switch (emailType) { + case 'simpleCTA': + case 'noCTA': + simplePartials.forEach(partial => handlePartial(partial, replacements)) + break + case 'invitation': + invitationPartials.forEach(partial => + handlePartial(partial, replacements), + ) + break + case 'notification': + notificationPartials.forEach(partial => + handlePartial(partial, replacements), + ) + break + default: + break + } + return getMainTemplate(emailType, replacements) +} + +const readFile = path => + fs.readFileSync(path, { encoding: 'utf-8' }, (err, file) => { + if (err) { + throw err + } else { + return file + } + }) + +const handlePartial = (partialName = 'signature', context = {}) => { + let partial = readFile( + `${__dirname}/../templates/partials/${partialName}.hbs`, + ) + const template = handlebars.compile(partial) + partial = template(context) + handlebars.registerPartial(partialName, partial) +} + +const getMainTemplate = (fileName, context) => { + const htmlFile = readFile(`${__dirname}/../templates/${fileName}.html`) + const htmlTemplate = handlebars.compile(htmlFile) + const htmlBody = htmlTemplate(context) + return htmlBody +} + +const getExpectedDate = (timestamp, daysExpected) => { + const date = new Date(timestamp) + let expectedDate = date.getDate() + daysExpected + date.setDate(expectedDate) + expectedDate = date.toLocaleDateString('en-US', { + day: 'numeric', + month: 'long', + year: 'numeric', + }) + return expectedDate +} + +module.exports = { + getBody, + createUrl, + getEmailBody, + getExpectedDate, + getNotificationBody, + getInvitationBody, +} diff --git a/packages/component-helper-service/src/services/email/templates/invitation.html b/packages/component-helper-service/src/services/email/templates/invitation.html new file mode 100644 index 0000000000000000000000000000000000000000..e48b106ecb4b622b0131103e70f7caa86fe1fbe4 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/invitation.html @@ -0,0 +1,5 @@ +{{> invitationHeader }} +{{> invitationUpperContent }} +{{> invitationButtons }} +{{> invitationLowerContent }} +{{> footer }} \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/noCTA.html b/packages/component-helper-service/src/services/email/templates/noCTA.html new file mode 100644 index 0000000000000000000000000000000000000000..63214091779bd60eac26f4f52433156083f5033f --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/noCTA.html @@ -0,0 +1,3 @@ +{{> header }} +{{> mainBody }} +{{> footer }} diff --git a/packages/component-helper-service/src/services/email/templates/notification.html b/packages/component-helper-service/src/services/email/templates/notification.html new file mode 100644 index 0000000000000000000000000000000000000000..56554d0f77a46d29e2ecddae448d48c2176c5ce3 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/notification.html @@ -0,0 +1,3 @@ +{{> notificationHeader}} +{{> notificationBody}} +{{> footer}} \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/footer.hbs b/packages/component-helper-service/src/services/email/templates/partials/footer.hbs new file mode 100644 index 0000000000000000000000000000000000000000..355088275373e0378176b00ca6a9007cc2d54a62 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/footer.hbs @@ -0,0 +1,36 @@ +<div data-role="module-unsubscribe" class="module unsubscribe-css__unsubscribe___2CDlR" role="module" data-type="unsubscribe" + style="color:#444444;font-size:12px;line-height:20px;padding:16px 16px 16px 16px;text-align:center"> + <div class="Unsubscribe--addressLine"> + <p class="Unsubscribe--senderName" style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">Hindawi Publishing Corporation</p> + <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px"> + <span class="Unsubscribe--senderAddress">315 Madison Ave, Third Floor, Suite 3070</span>, + <span class="Unsubscribe--senderCity">NEW YORK</span>, + <span class="Unsubscribe--senderState">NY</span> + <span class="Unsubscribe--senderZip">10017</span> + </p> + </div> + <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px"> + <a class="Unsubscribe--unsubscribeLink" href="{{ unsubscribeLink }}">Unsubscribe</a> + </p> +</div> +</td> +</tr> +</table> +<!--[if mso]> + </td></tr></table> + </center> + <![endif]--> +</td> +</tr> +</table> +</td> +</tr> +</table> +</td> +</tr> +</table> +</div> +</center> +</body> + +</html> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/header.hbs b/packages/component-helper-service/src/services/email/templates/partials/header.hbs new file mode 100644 index 0000000000000000000000000000000000000000..3e8efa3eaeff420f3bbf0e68bc88d48713410851 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/header.hbs @@ -0,0 +1,161 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> + +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> + <!--[if !mso]><!--> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <!--<![endif]--> + <!--[if (gte mso 9)|(IE)]> + <xml> + <o:OfficeDocumentSettings> + <o:AllowPNG/> + <o:PixelsPerInch>96</o:PixelsPerInch> + </o:OfficeDocumentSettings> + </xml> + <![endif]--> + <!--[if (gte mso 9)|(IE)]> + <style type="text/css"> + body {width: 600px;margin: 0 auto;} + table {border-collapse: collapse;} + table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;} + img {-ms-interpolation-mode: bicubic;} + </style> + <![endif]--> + + <style type="text/css"> + body, + p, + div { + font-family: helvetica, arial, sans-serif; + font-size: 14px; + } + + body { + color: #626262; + } + + body a { + color: #0D78F2; + text-decoration: none; + } + + p { + margin: 0; + padding: 0; + } + + table.wrapper { + width: 100% !important; + table-layout: fixed; + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + } + + img.max-width { + max-width: 100% !important; + } + + .column.of-2 { + width: 50%; + } + + .column.of-3 { + width: 33.333%; + } + + .column.of-4 { + width: 25%; + } + + @media screen and (max-width:480px) { + .preheader .rightColumnContent, + .footer .rightColumnContent { + text-align: left !important; + } + .preheader .rightColumnContent div, + .preheader .rightColumnContent span, + .footer .rightColumnContent div, + .footer .rightColumnContent span { + text-align: left !important; + } + .preheader .rightColumnContent, + .preheader .leftColumnContent { + font-size: 80% !important; + padding: 5px 0; + } + table.wrapper-mobile { + width: 100% !important; + table-layout: fixed; + } + img.max-width { + height: auto !important; + max-width: 480px !important; + } + a.bulletproof-button { + display: block !important; + width: auto !important; + font-size: 80%; + padding-left: 0 !important; + padding-right: 0 !important; + } + .columns { + width: 100% !important; + } + .column { + display: block !important; + width: 100% !important; + padding-left: 0 !important; + padding-right: 0 !important; + margin-left: 0 !important; + margin-right: 0 !important; + } + } + </style> + <!--user entered Head Start--> + + <!--End Head user entered--> +</head> + +<body> + <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;"> + <div class="webkit"> + <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4"> + <tr> + <td valign="top" bgcolor="#F4F4F4" width="100%"> + <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0"> + <tr> + <td width="100%"> + <table width="100%" cellpadding="0" cellspacing="0" border="0"> + <tr> + <td> + <!--[if mso]> + <center> + <table><tr><td width="600"> + <![endif]--> + <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center"> + <tr> + <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%" + align="left"> + + <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" + width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> + <tr> + <td role="module-content"> + <p>{{ previewText }}</p> + </td> + </tr> + </table> + + <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> + <tr> + <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center"> + <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;" + src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png" + alt="" width="60"> + </td> + </tr> + </table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invitationButtons.hbs b/packages/component-helper-service/src/services/email/templates/partials/invitationButtons.hbs new file mode 100644 index 0000000000000000000000000000000000000000..002013ea2b7fa1e76bf6441fed608f79d0a8c99b --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/invitationButtons.hbs @@ -0,0 +1,88 @@ +<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" role="module" data-type="columns" data-version="2" + style="padding:20px 0px 20px 0px;background-color:#ffffff;box-sizing:border-box;" bgcolor="#ffffff"> + <tr role='module-content'> + <td height="100%" valign="top"> + <!--[if (gte mso 9)|(IE)]> + <center> + <table cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;border-collapse:collapse;table-layout: fixed;" > + <tr> + <![endif]--> + + <!--[if (gte mso 9)|(IE)]> + <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" > + <![endif]--> + + <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;" cellpadding="0" + cellspacing="0" align="left" border="0" bgcolor="#ffffff" class="column column-0 of-2 + empty"> + <tr> + <td style="padding:0px;margin:0px;border-spacing:0;"> + <table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" + style="table-layout:fixed" width="100%"> + <tbody> + <tr> + <td align="center" class="outer-td" style="padding:0px 0px 0px 0px"> + <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> + <tbody> + <tr> + <td align="center" bgcolor="#0d78f2" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> + <a style="background-color:#0d78f2;border:1px solid #333333;border-color:#0d78f2;border-radius:0px;border-width:1px;color:#ffffff;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" + href="{{agreeUrl}}" target="_blank">AGREE</a> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + </table> + + <!--[if (gte mso 9)|(IE)]> + </td> + <![endif]--> + <!--[if (gte mso 9)|(IE)]> + <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" > + <![endif]--> + + <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;" cellpadding="0" + cellspacing="0" align="left" border="0" bgcolor="#ffffff" class="column column-1 of-2 + empty"> + <tr> + <td style="padding:0px;margin:0px;border-spacing:0;"> + <table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" + style="table-layout:fixed" width="100%"> + <tbody> + <tr> + <td align="center" class="outer-td" style="padding:0px 0px 0px 0px"> + <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> + <tbody> + <tr> + <td align="center" bgcolor="#e4dfdf" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> + <a style="background-color:#e4dfdf;border:1px solid #333333;border-color:#E4DFDF;border-radius:0px;border-width:1px;color:#302e2e;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" + href="{{declineUrl}}" target="_blank">DECLINE</a> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + </table> + + <!--[if (gte mso 9)|(IE)]> + </td> + <![endif]--> + <!--[if (gte mso 9)|(IE)]> + <tr> + </table> + </center> + <![endif]--> + </td> + </tr> +</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invitationHeader.hbs b/packages/component-helper-service/src/services/email/templates/partials/invitationHeader.hbs new file mode 100644 index 0000000000000000000000000000000000000000..3e8efa3eaeff420f3bbf0e68bc88d48713410851 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/invitationHeader.hbs @@ -0,0 +1,161 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> + +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> + <!--[if !mso]><!--> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <!--<![endif]--> + <!--[if (gte mso 9)|(IE)]> + <xml> + <o:OfficeDocumentSettings> + <o:AllowPNG/> + <o:PixelsPerInch>96</o:PixelsPerInch> + </o:OfficeDocumentSettings> + </xml> + <![endif]--> + <!--[if (gte mso 9)|(IE)]> + <style type="text/css"> + body {width: 600px;margin: 0 auto;} + table {border-collapse: collapse;} + table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;} + img {-ms-interpolation-mode: bicubic;} + </style> + <![endif]--> + + <style type="text/css"> + body, + p, + div { + font-family: helvetica, arial, sans-serif; + font-size: 14px; + } + + body { + color: #626262; + } + + body a { + color: #0D78F2; + text-decoration: none; + } + + p { + margin: 0; + padding: 0; + } + + table.wrapper { + width: 100% !important; + table-layout: fixed; + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + } + + img.max-width { + max-width: 100% !important; + } + + .column.of-2 { + width: 50%; + } + + .column.of-3 { + width: 33.333%; + } + + .column.of-4 { + width: 25%; + } + + @media screen and (max-width:480px) { + .preheader .rightColumnContent, + .footer .rightColumnContent { + text-align: left !important; + } + .preheader .rightColumnContent div, + .preheader .rightColumnContent span, + .footer .rightColumnContent div, + .footer .rightColumnContent span { + text-align: left !important; + } + .preheader .rightColumnContent, + .preheader .leftColumnContent { + font-size: 80% !important; + padding: 5px 0; + } + table.wrapper-mobile { + width: 100% !important; + table-layout: fixed; + } + img.max-width { + height: auto !important; + max-width: 480px !important; + } + a.bulletproof-button { + display: block !important; + width: auto !important; + font-size: 80%; + padding-left: 0 !important; + padding-right: 0 !important; + } + .columns { + width: 100% !important; + } + .column { + display: block !important; + width: 100% !important; + padding-left: 0 !important; + padding-right: 0 !important; + margin-left: 0 !important; + margin-right: 0 !important; + } + } + </style> + <!--user entered Head Start--> + + <!--End Head user entered--> +</head> + +<body> + <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;"> + <div class="webkit"> + <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4"> + <tr> + <td valign="top" bgcolor="#F4F4F4" width="100%"> + <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0"> + <tr> + <td width="100%"> + <table width="100%" cellpadding="0" cellspacing="0" border="0"> + <tr> + <td> + <!--[if mso]> + <center> + <table><tr><td width="600"> + <![endif]--> + <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center"> + <tr> + <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%" + align="left"> + + <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" + width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> + <tr> + <td role="module-content"> + <p>{{ previewText }}</p> + </td> + </tr> + </table> + + <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> + <tr> + <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center"> + <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;" + src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png" + alt="" width="60"> + </td> + </tr> + </table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invitationLowerContent.hbs b/packages/component-helper-service/src/services/email/templates/partials/invitationLowerContent.hbs new file mode 100644 index 0000000000000000000000000000000000000000..ef60e6b2aa6d9d303515dfc6feead9c054c30cc6 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/invitationLowerContent.hbs @@ -0,0 +1,18 @@ +<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> + <tr> + <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> + <p data-pm-slice="1 1 []"> + <a href="{{ manuscriptDetailsUrl }}">See more information</a> + </p> + + <p data-pm-slice="1 1 []"> </p> + + {{> manuscriptData }} + <p data-pm-slice="1 1 []">{{{ lowerContent }}}</p> + + <p> </p> + {{> signature }} + <div style="text-align: center;"> </div> + </td> + </tr> +</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invitationUpperContent.hbs b/packages/component-helper-service/src/services/email/templates/partials/invitationUpperContent.hbs new file mode 100644 index 0000000000000000000000000000000000000000..1bacf2e791241303b5242c62b5f2393a6dc43930 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/invitationUpperContent.hbs @@ -0,0 +1,13 @@ +<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> + <tr> + <td style="padding:30px 23px 20px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> + <div> + <p data-pm-slice="1 1 []">{{ intro }},</p> + + <p> </p> + <p>{{ upperContent }}</p> + </div> + + </td> + </tr> +</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/mainBody.hbs b/packages/component-helper-service/src/services/email/templates/partials/mainBody.hbs new file mode 100644 index 0000000000000000000000000000000000000000..6fb579666eab6f2477f7d40e50f7d563fa47bb80 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/mainBody.hbs @@ -0,0 +1,10 @@ +<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> + <tr> + <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> + <h1 style="text-align: center;">{{ headline }}</h1> + <div style="text-align: center;">{{ paragraph }}</div> + <div style="text-align: center;"> </div> + <div style="text-align: center;"> </div> + </td> + </tr> +</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/mainButton.hbs b/packages/component-helper-service/src/services/email/templates/partials/mainButton.hbs new file mode 100644 index 0000000000000000000000000000000000000000..9833fff520dd7a266851ca078aed1dbe899874f8 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/mainButton.hbs @@ -0,0 +1,19 @@ +<table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" + style="table-layout:fixed" width="100%"> + <tbody> + <tr> + <td align="center" bgcolor="#FFFFFF" class="outer-td" style="padding:0px 0px 30px 0px;background-color:#FFFFFF"> + <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> + <tbody> + <tr> + <td align="center" bgcolor="#0d78f2" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> + <a href="{{ url }}" style="background-color:#0d78f2;border:1px solid #333333;border-color:#0d78f2;border-radius:0px;border-width:1px;color:#ffffff;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" + target="_blank">{{ buttonText }}</a> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> +</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/manuscriptData.hbs b/packages/component-helper-service/src/services/email/templates/partials/manuscriptData.hbs new file mode 100644 index 0000000000000000000000000000000000000000..26bb10cc98d9ad17cc93ab99bc462cd63f2f9d50 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/manuscriptData.hbs @@ -0,0 +1,15 @@ +<p data-pm-slice="1 1 []">{{ manuscriptText }}</p> +<p> </p> +<h2>{{title}}</h2> +<p> </p> +<h4> + <span style="font-family:arial,helvetica,sans-serif;">{{authors}}</span> +</h4> +<p> + <br /> + <em> + <span style="font-family:arial,helvetica,sans-serif;">{{{abstract}}}</span> + </em> +</p> + +<p> </p> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/manuscriptDetailsLink.hbs b/packages/component-helper-service/src/services/email/templates/partials/manuscriptDetailsLink.hbs new file mode 100644 index 0000000000000000000000000000000000000000..133841f72b5f82aa572a674fd0d7a079619e689b --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/manuscriptDetailsLink.hbs @@ -0,0 +1 @@ + {{ beforeAnchor }} <a href="{{ detailsUrl }}">manuscript details page</a> {{ afterAnchor}}. \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/notificationBody.hbs b/packages/component-helper-service/src/services/email/templates/partials/notificationBody.hbs new file mode 100644 index 0000000000000000000000000000000000000000..310722e99b26d50e269da57bf0f3c8b7023cc580 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/notificationBody.hbs @@ -0,0 +1,20 @@ +<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> + <tr> + <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> + <div> + <p data-pm-slice="1 1 []">Dear Dr. {{toUserName}},</p> + <p> </p> + <p> + {{{paragraph}}} + {{#if hasLink }} + {{> manuscriptDetailsLink}} + {{/if}} + </p> + <p> </p> + {{> signature}} + <p> </p> + </div> + + </td> + </tr> +</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/notificationHeader.hbs b/packages/component-helper-service/src/services/email/templates/partials/notificationHeader.hbs new file mode 100644 index 0000000000000000000000000000000000000000..a62d4be742baba10db155a84f6db8e6535880c7b --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/notificationHeader.hbs @@ -0,0 +1,161 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> + +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> + <!--[if !mso]><!--> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <!--<![endif]--> + <!--[if (gte mso 9)|(IE)]> + <xml> + <o:OfficeDocumentSettings> + <o:AllowPNG/> + <o:PixelsPerInch>96</o:PixelsPerInch> + </o:OfficeDocumentSettings> + </xml> + <![endif]--> + <!--[if (gte mso 9)|(IE)]> + <style type="text/css"> + body {width: 600px;margin: 0 auto;} + table {border-collapse: collapse;} + table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;} + img {-ms-interpolation-mode: bicubic;} + </style> + <![endif]--> + + <style type="text/css"> + body, + p, + div { + font-family: helvetica, arial, sans-serif; + font-size: 14px; + } + + body { + color: #626262; + } + + body a { + color: #0D78F2; + text-decoration: none; + } + + p { + margin: 0; + padding: 0; + } + + table.wrapper { + width: 100% !important; + table-layout: fixed; + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + } + + img.max-width { + max-width: 100% !important; + } + + .column.of-2 { + width: 50%; + } + + .column.of-3 { + width: 33.333%; + } + + .column.of-4 { + width: 25%; + } + + @media screen and (max-width:480px) { + .preheader .rightColumnContent, + .footer .rightColumnContent { + text-align: left !important; + } + .preheader .rightColumnContent div, + .preheader .rightColumnContent span, + .footer .rightColumnContent div, + .footer .rightColumnContent span { + text-align: left !important; + } + .preheader .rightColumnContent, + .preheader .leftColumnContent { + font-size: 80% !important; + padding: 5px 0; + } + table.wrapper-mobile { + width: 100% !important; + table-layout: fixed; + } + img.max-width { + height: auto !important; + max-width: 480px !important; + } + a.bulletproof-button { + display: block !important; + width: auto !important; + font-size: 80%; + padding-left: 0 !important; + padding-right: 0 !important; + } + .columns { + width: 100% !important; + } + .column { + display: block !important; + width: 100% !important; + padding-left: 0 !important; + padding-right: 0 !important; + margin-left: 0 !important; + margin-right: 0 !important; + } + } + </style> + <!--user entered Head Start--> + + <!--End Head user entered--> +</head> + +<body> + <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;"> + <div class="webkit"> + <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4"> + <tr> + <td valign="top" bgcolor="#F4F4F4" width="100%"> + <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0"> + <tr> + <td width="100%"> + <table width="100%" cellpadding="0" cellspacing="0" border="0"> + <tr> + <td> + <!--[if mso]> + <center> + <table><tr><td width="600"> + <![endif]--> + <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center"> + <tr> + <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%" + align="left"> + + <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" + width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> + <tr> + <td role="module-content"> + <p>you have a new notification</p> + </td> + </tr> + </table> + + <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> + <tr> + <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center"> + <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;" + src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png" + alt="" width="60"> + </td> + </tr> + </table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/signature.hbs b/packages/component-helper-service/src/services/email/templates/partials/signature.hbs new file mode 100644 index 0000000000000000000000000000000000000000..29cb70c53ef98e4eef1e0fb01dff1eb925320151 --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/partials/signature.hbs @@ -0,0 +1,5 @@ +<p>With many thanks and best regards, + <br /> {{ signatureName }} + <br /> {{ signatureEmail }} + <br /> Hindawi +</p> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/simpleCTA.html b/packages/component-helper-service/src/services/email/templates/simpleCTA.html new file mode 100644 index 0000000000000000000000000000000000000000..4d5a97b25445b85f27874470ab76864ccc45b3dd --- /dev/null +++ b/packages/component-helper-service/src/services/email/templates/simpleCTA.html @@ -0,0 +1,4 @@ +{{> header }} +{{> mainBody }} +{{> mainButton }} +{{> footer }} diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js index f63cec1123e08e243a46641ca8fc21b5c75b8038..0ee596f81ff579622fec436f937ba0300e0762aa 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js @@ -1,6 +1,9 @@ const uuid = require('uuid') -const { chain, pick } = require('lodash') +const config = require('config') +const { chain, pick, get } = require('lodash') + const { + User, Email, services, authsome: authsomeHelper, @@ -8,6 +11,8 @@ const { Collection, } = require('pubsweet-component-helper-service') +const unsubscribeSlug = config.get('unsubscribe.url') + module.exports = models => async (req, res) => { const { recommendation, comments, recommendationType } = req.body if (!services.checkForUndefinedParams(recommendationType)) @@ -54,9 +59,12 @@ module.exports = models => async (req, res) => { newRecommendation.recommendation = recommendation || undefined newRecommendation.comments = comments || undefined + const UserModel = models.User const collectionHelper = new Collection({ collection }) const fragmentHelper = new Fragment({ fragment }) + const userHelper = new User({ UserModel }) + const parsedFragment = await fragmentHelper.getFragmentData({ handlingEditor: collection.handlingEditor, }) @@ -65,72 +73,140 @@ module.exports = models => async (req, res) => { const authors = await fragmentHelper.getAuthorData({ UserModel }) const email = new Email({ - UserModel, - collection, - parsedFragment, - baseUrl, - authors, + type: 'user', + content: { + subject: `${collection.customId}: Manuscript`, + titleText: `the manuscript titled "${parsedFragment.title}" by ${ + authors.submittingAuthor.firstName + } ${authors.submittingAuthor.firstName}`, + }, + signatureName: get(collection, 'handlingEditor.name'), + comments: parsedFragment.newComments, }) - const FragmentModel = models.Fragment + + const { name: eicName } = await userHelper.getEditorInChief() if (reqUser.editorInChief || reqUser.admin) { + const eicComments = chain(newRecommendation) + .get('comments') + .find(comm => !comm.public) + .get('content') + .value() + email.content.comments = eicComments + sendHandlingEditorEmail({ + recommendation, + email, + handlingEditor: get(collection, 'handlingEditor', {}), + eicName, + baseUrl, + }) + if (recommendation === 'return-to-handling-editor') { collectionHelper.updateStatus({ newStatus: 'reviewCompleted' }) - const eicComments = chain(newRecommendation) - .get('comments') - .find(comm => !comm.public) - .get('content') - .value() - email.parsedFragment.eicComments = eicComments - email.setupHandlingEditorEmail({ - returnWithComments: true, - }) } else { collectionHelper.updateFinalStatusByRecommendation({ recommendation, }) - email.setupAuthorsEmail({ - requestToRevision: false, - publish: recommendation === 'publish', - FragmentModel, - }) - email.setupHandlingEditorEmail({ - publish: recommendation === 'publish', - }) - email.parsedFragment.recommendations = fragment.recommendations - email.setupReviewersEmail({ - recommendation, - isSubmitted: true, - agree: true, - FragmentModel, - }) + + sendAuthorsEmail({ recommendation, email, baseUrl, authors }) + + // email.parsedFragment.recommendations = fragment.recommendations + // email.setupReviewersEmail({ + // recommendation, + // isSubmitted: true, + // agree: true, + // FragmentModel, + // }) } } else if (recommendationType === 'editorRecommendation') { collectionHelper.updateStatusByRecommendation({ recommendation, isHandlingEditor: true, }) - email.setupReviewersEmail({ - recommendation, - agree: true, - FragmentModel, - }) - email.setupReviewersEmail({ agree: false, FragmentModel: models.Fragment }) - email.setupEiCEmail({ - recommendation, - comments: newRecommendation.comments, - }) + // email.setupReviewersEmail({ + // recommendation, + // agree: true, + // FragmentModel, + // }) + // email.setupReviewersEmail({ agree: false, FragmentModel: models.Fragment }) + // email.setupEiCEmail({ + // recommendation, + // comments: newRecommendation.comments, + // }) if (['minor', 'major'].includes(recommendation)) { fragment.revision = pick(fragment, ['authors', 'files', 'metadata']) - email.parsedFragment.newComments = newRecommendation.comments - email.setupAuthorsEmail({ - requestToRevision: true, - }) + // email.parsedFragment.newComments = newRecommendation.comments + // email.setupAuthorsEmail({ + // requestToRevision: true, + // }) } } + fragment.recommendations.push(newRecommendation) await fragment.save() return res.status(200).json(newRecommendation) } + +const sendHandlingEditorEmail = ({ + recommendation, + email, + handlingEditor, + eicName, + baseUrl, +}) => { + let emailType + 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-reject' + break + default: + throw new Error(`undefined recommendation: ${recommendation} `) + } + + email.toUser = { + email: handlingEditor.email, + name: `${handlingEditor.name}`, + } + email.content.unsubscribeLink = services.createUrl(baseUrl, unsubscribeSlug, { + id: handlingEditor.id, + }) + email.content.subject = `${email.content.subject} Decision` + email.content.signatureName = eicName + const { html, text } = email.getBody(emailType) + email.sendEmail({ html, text }) +} + +const sendAuthorsEmail = ({ recommendation, email, baseUrl, authors }) => { + let emailType + if (recommendation === 'publish') { + emailType = 'author-manuscript-published' + email.content.subject = `${email.content.subject} Published` + } else { + emailType = 'author-manuscript-rejected' + email.content.subject = `${email.content.subject} Rejected` + } + + authors.forEach(author => { + email.toUser = { + email: author.email, + name: `${author.firstName} ${author.lastName}`, + } + email.content.unsubscribeLink = services.createUrl( + baseUrl, + unsubscribeSlug, + { + id: author.id, + }, + ) + const { html, text } = email.getBody(emailType) + email.sendEmail({ html, text }) + }) +}