diff --git a/packages/component-mail-service/src/Mail.js b/packages/component-mail-service/src/Mail.js
index c0886c2c27eb3b21b408b5d88dd36c9aa89204e1..69ffa1481fd9b4562d66d646f8b553654aff8c50 100644
--- a/packages/component-mail-service/src/Mail.js
+++ b/packages/component-mail-service/src/Mail.js
@@ -44,11 +44,11 @@ module.exports = {
         } ${replacements.buttonText}`
         break
       case 'invite-author':
-        subject = 'Hindawi Invitation'
+        subject = 'Author Invitation'
         replacements.headline =
-          'You have been invited as an Author to a manuscript.'
+          'You have been invited to join Hindawi as an Author.'
         replacements.paragraph =
-          "The manuscript will be visible on your dashboard once it's submitted. Please confirm your account and set your account details by clicking on the link below."
+          'Please confirm your account and set your account details by clicking on the link below.'
         replacements.previewText = 'You have been invited'
         replacements.buttonText = 'CONFIRM'
         replacements.url = helpers.createUrl(dashboardUrl, resetPath, {
@@ -305,8 +305,8 @@ module.exports = {
         replacements.intro = `Dear ${meta.handlingEditorName}`
 
         replacements.paragraph = `We are pleased to inform you that Dr. ${
-          user.firstName
-        } ${user.lastName} has submitted a review for the manuscript titled "${
+          meta.reviewerName
+        } has submitted a review for the manuscript titled "${
           meta.fragment.title
         }" by ${meta.fragment.authorName}.`
         replacements.beforeAnchor = 'Please visit the'
@@ -404,16 +404,16 @@ module.exports = {
         subject = meta.emailSubject
         replacements.hasLink = false
         replacements.previewText = 'a manuscript has reached a decision'
-        replacements.intro = `Dear Dr. ${user.firstName} ${user.lastName}`
+        replacements.intro = `Dear Dr. ${meta.reviewerName}`
 
         replacements.paragraph = `An editorial decision has been made regarding the ${
           meta.manuscriptType
         } titled "${meta.fragment.title}" by ${
           meta.fragment.authorName
-        }. So, you do not need to proceed with the review of this manuscript. <br/>
+        }. 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.`
         delete replacements.detailsUrl
-        replacements.signatureName = meta.handlingEditorName
+        replacements.signatureName = meta.editorName
         textBody = `${replacements.intro} ${replacements.paragraph} ${
           replacements.signatureName
         }`
diff --git a/packages/component-manuscript-manager/src/helpers/Collection.js b/packages/component-manuscript-manager/src/helpers/Collection.js
index b5e783c80c7fb320ef269fc863544fafd5604eed..7868b5b9481903203443d0a63c8fc0a716c95d65 100644
--- a/packages/component-manuscript-manager/src/helpers/Collection.js
+++ b/packages/component-manuscript-manager/src/helpers/Collection.js
@@ -40,11 +40,7 @@ const updateStatus = async (collection, newStatus) => {
   await collection.save()
 }
 
-const getFragmentAndAuthorData = async ({
-  UserModel,
-  fragment,
-  collection: { authors, handlingEditor },
-}) => {
+const getFragmentData = async ({ fragment, handlingEditor }) => {
   const heRecommendation = fragment.recommendations.find(
     rec => rec.userId === handlingEditor.id,
   )
@@ -53,6 +49,17 @@ const getFragmentAndAuthorData = async ({
   title = title.replace(/<(.|\n)*?>/g, '')
   abstract = abstract ? abstract.replace(/<(.|\n)*?>/g, '') : ''
 
+  return {
+    title,
+    abstract,
+    type,
+    heRecommendation,
+    recommendations: fragment.recommendations,
+    id: fragment.id,
+  }
+}
+
+const getAuthorData = async ({ authors, UserModel }) => {
   const submittingAuthorData = authors.find(
     author => author.isSubmitting === true,
   )
@@ -62,28 +69,30 @@ const getFragmentAndAuthorData = async ({
     return `${user.firstName} ${user.lastName}`
   })
   const authorsList = await Promise.all(authorsPromises)
+
   return {
-    title,
-    submittingAuthor,
-    abstract,
     authorsList,
-    type,
-    heRecommendation,
+    submittingAuthor,
   }
 }
 
-const getAgreedReviewerInvitation = (invitations = []) =>
-  invitations.filter(
-    inv =>
-      inv.role === 'reviewer' &&
-      inv.hasAnswer === true &&
-      inv.isAccepted === true,
-  )
+const getReviewerInvitations = (invitations = [], agree = true) =>
+  agree
+    ? invitations.filter(
+        inv =>
+          inv.role === 'reviewer' &&
+          inv.hasAnswer === true &&
+          inv.isAccepted === true,
+      )
+    : invitations.filter(
+        inv => inv.role === 'reviewer' && inv.hasAnswer === false,
+      )
 
 module.exports = {
   updateStatusByRecommendation,
-  getFragmentAndAuthorData,
-  getAgreedReviewerInvitation,
+  getFragmentData,
+  getAuthorData,
+  getReviewerInvitations,
   updateStatus,
   updateFinalStatusByRecommendation,
 }
diff --git a/packages/component-manuscript-manager/src/helpers/Email.js b/packages/component-manuscript-manager/src/helpers/Email.js
new file mode 100644
index 0000000000000000000000000000000000000000..044dc1797d147d1fa7f1909c1395b6e6e694fb25
--- /dev/null
+++ b/packages/component-manuscript-manager/src/helpers/Email.js
@@ -0,0 +1,261 @@
+const collectionHelper = require('./Collection')
+const get = require('lodash/get')
+const config = require('config')
+const mailService = require('pubsweet-component-mail-service')
+
+const manuscriptTypes = config.get('manuscript-types')
+
+class Email {
+  constructor({
+    baseUrl,
+    authors = {},
+    UserModel = {},
+    collection = {},
+    parsedFragment = {},
+  }) {
+    this.baseUrl = baseUrl
+    this.authors = authors
+    this.UserModel = UserModel
+    this.collection = collection
+    this.parsedFragment = parsedFragment
+  }
+
+  set _fragment(newFragment) {
+    this.parsedFragment = newFragment
+  }
+
+  async setupReviewersEmail({
+    recommendation = {},
+    isSubmitted = false,
+    agree = false,
+  }) {
+    const {
+      UserModel,
+      parsedFragment: { recommendations, title, type },
+      authors: { submittingAuthor: { firstName = '', lastName = '' } },
+      collection: {
+        customId,
+        invitations = [],
+        handlingEditor: { name: heName },
+      },
+    } = this
+
+    const reviewerInvitations = collectionHelper.getReviewerInvitations(
+      invitations,
+      agree,
+    )
+
+    const hasReview = invUserId => rec =>
+      rec.recommendationType === 'review' &&
+      rec.submittedOn &&
+      invUserId === rec.userId
+
+    const reviewerPromises = await reviewerInvitations.map(async inv => {
+      if (!agree) return UserModel.find(inv.userId)
+      const submittedReview = recommendations.find(hasReview(inv.userId))
+      const shouldReturnUser =
+        (isSubmitted && submittedReview) || (!isSubmitted && !submittedReview)
+      if (shouldReturnUser) return UserModel.find(inv.userId)
+    })
+    let emailType = 'agreed-reviewers-after-recommendation'
+    let emailText, subject, manuscriptType
+    const eic = await getEditorInChief(UserModel)
+    const editorName = isSubmitted ? `${eic.firstName} ${eic.lastName}` : heName
+
+    let reviewers = await Promise.all(reviewerPromises)
+    reviewers = reviewers.filter(Boolean)
+    if (agree) {
+      subject = isSubmitted
+        ? `${customId}: Manuscript Decision`
+        : `${customId}: Manuscript ${getSubject(recommendation)}`
+
+      if (isSubmitted) {
+        emailType = 'submitting-reviewers-after-decision'
+        emailText = 'has now been rejected'
+        if (recommendation === 'publish') emailText = 'will now be published'
+      }
+    } else {
+      subject = `${customId}: Reviewer Unassigned`
+      manuscriptType = manuscriptTypes[type]
+      emailType = 'no-response-reviewers-after-recommendation'
+    }
+
+    reviewers.forEach(user =>
+      mailService.sendNotificationEmail({
+        emailType,
+        toEmail: user.email,
+        meta: {
+          emailText,
+          editorName,
+          manuscriptType,
+          emailSubject: subject,
+          reviewerName: `${user.firstName} ${user.lastName}`,
+          fragment: {
+            title,
+            authorName: `${firstName} ${lastName}`,
+          },
+        },
+      }),
+    )
+  }
+
+  async setupAuthorsEmail({ requestToRevision = false, publish = false }) {
+    const {
+      baseUrl,
+      collection,
+      parsedFragment: { heRecommendation, id, title, newComments },
+      authors: { submittingAuthor: { email, firstName, lastName } },
+    } = this
+    let comments = get(heRecommendation, 'comments') || []
+    if (requestToRevision) comments = newComments
+    const authorNote = comments.find(comm => comm.public)
+    const content = get(authorNote, 'content')
+    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 = [
+        {
+          email,
+          name: `${firstName} ${lastName}`,
+        },
+      ]
+    } else {
+      toAuthors = collection.authors.map(author => ({
+        email: author.email,
+        name: `${author.firstName} ${author.lastName}`,
+      }))
+    }
+    toAuthors.forEach(toAuthor => {
+      mailService.sendNotificationEmail({
+        baseUrl,
+        emailType,
+        toEmail: toAuthor.email,
+        handlingEditorName: collection.handlingEditor.name,
+        meta: {
+          collection,
+          authorNoteText,
+          fragment: {
+            id,
+            title,
+            authorName: toAuthor.name,
+            submittingAuthorName: `${firstName} ${lastName}`,
+          },
+        },
+      })
+    })
+  }
+
+  async setupHandlingEditorEmail({
+    publish = false,
+    reviewSubmitted = false,
+    reviewerName = '',
+  }) {
+    const {
+      baseUrl,
+      UserModel,
+      collection,
+      parsedFragment: { title, id },
+      authors: { submittingAuthor: { firstName = '', lastName = '' } },
+    } = this
+    const eic = await getEditorInChief(UserModel)
+    const toEmail = collection.handlingEditor.email
+    let emailType = publish
+      ? 'he-manuscript-published'
+      : 'he-manuscript-rejected'
+    if (reviewSubmitted) emailType = 'review-submitted'
+    mailService.sendNotificationEmail({
+      toEmail,
+      baseUrl,
+      emailType,
+      meta: {
+        collection,
+        reviewerName,
+        eicName: `${eic.firstName} ${eic.lastName}`,
+        handlingEditorName: collection.handlingEditor.name,
+        emailSubject: `${collection.customId}: Manuscript Decision`,
+        fragment: {
+          id,
+          title,
+          authorName: `${firstName} ${lastName}`,
+        },
+      },
+    })
+  }
+
+  async setupEiCEmail({ recommendation, comments }) {
+    const {
+      baseUrl,
+      UserModel,
+      collection,
+      parsedFragment: { title, id },
+      authors: { submittingAuthor: { firstName, lastName } },
+    } = this
+    const privateNote = comments.find(comm => comm.public === false)
+    const content = get(privateNote, 'content')
+    const privateNoteText =
+      content !== undefined ? `Private note: "${content}"` : ''
+    let paragraph
+    const heRecommendation = getHeRecommendation(recommendation)
+    const manuscriptAuthorText = `the manuscript titled "${title}" by ${firstName} ${lastName}`
+    const publishOrRejectText =
+      'It is my recommendation, based on the reviews I have received for'
+    switch (heRecommendation) {
+      case 'publish':
+        paragraph = `${publishOrRejectText} ${manuscriptAuthorText}, that we should proceed to publication. <br/><br/>
+        ${privateNoteText}<br/><br/>`
+        break
+      case 'reject':
+        paragraph = `${publishOrRejectText}
+        ${manuscriptAuthorText}, that we should reject it for publication. <br/><br/>
+        ${privateNoteText}<br/><br/>`
+        break
+      case 'revision':
+        paragraph = `In order for ${manuscriptAuthorText} to proceed to publication, there needs to be a revision. <br/><br/>
+        ${privateNoteText}<br/><br/>`
+        break
+
+      default:
+        throw new Error('undefined HE recommentation type')
+    }
+
+    const eic = await getEditorInChief(UserModel)
+    const toEmail = eic.email
+    mailService.sendNotificationEmail({
+      toEmail,
+      emailType: 'eic-recommendation',
+      meta: {
+        baseUrl,
+        paragraph,
+        collection,
+        fragment: { id },
+        eicName: `${eic.firstName} ${eic.lastName}`,
+        handlingEditorName: collection.handlingEditor.name,
+      },
+    })
+  }
+}
+
+const getSubject = recommendation =>
+  ['minor', 'major'].includes(recommendation)
+    ? 'Revision Requested'
+    : 'Recommendation Submitted'
+
+const getHeRecommendation = recommendation => {
+  let heRecommendation = recommendation === 'reject' ? 'reject' : 'publish'
+  if (['minor', 'major'].includes(recommendation)) {
+    heRecommendation = 'revision'
+  }
+  return heRecommendation
+}
+
+const getEditorInChief = async UserModel => {
+  const users = await UserModel.all()
+  const eic = users.find(user => user.editorInChief || user.admin)
+  return eic
+}
+
+module.exports = Email
diff --git a/packages/component-manuscript-manager/src/helpers/User.js b/packages/component-manuscript-manager/src/helpers/User.js
deleted file mode 100644
index c9945c0ee80f60f09add3de038b360de877e56f9..0000000000000000000000000000000000000000
--- a/packages/component-manuscript-manager/src/helpers/User.js
+++ /dev/null
@@ -1,275 +0,0 @@
-const collectionHelper = require('./Collection')
-const get = require('lodash/get')
-const config = require('config')
-const mailService = require('pubsweet-component-mail-service')
-
-const manuscriptTypes = config.get('manuscript-types')
-const getEditorInChief = async UserModel => {
-  const users = await UserModel.all()
-  const eic = users.find(user => user.editorInChief || user.admin)
-  return eic
-}
-
-const setupReviewSubmittedEmailData = async ({
-  baseUrl,
-  UserModel,
-  fragment: { id, title, submittingAuthor },
-  collection,
-  user,
-}) => {
-  const eic = await getEditorInChief(UserModel)
-  const toEmail = collection.handlingEditor.email
-  await mailService.sendNotificationEmail({
-    toEmail,
-    user,
-    emailType: 'review-submitted',
-    meta: {
-      collection: { customId: collection.customId, id: collection.id },
-      fragment: {
-        id,
-        title,
-        authorName: `${submittingAuthor.firstName} ${
-          submittingAuthor.lastName
-        }`,
-      },
-      handlingEditorName: collection.handlingEditor.name,
-      baseUrl,
-      eicName: `${eic.firstName} ${eic.lastName}`,
-    },
-  })
-}
-
-const setupReviewersEmail = async ({
-  fragment: { title, authorName, recommendations },
-  collection,
-  UserModel,
-  recommendation,
-  isSubmitted = false,
-}) => {
-  const agreedReviewerInvitations = collectionHelper.getAgreedReviewerInvitation(
-    collection.invitations,
-  )
-  const hasReview = invUserId => rec =>
-    rec.recommendationType === 'review' &&
-    rec.submittedOn &&
-    invUserId === rec.userId
-  const reviewerPromises = await agreedReviewerInvitations.map(async inv => {
-    const submittedReview = recommendations.find(hasReview(inv.userId))
-    const shouldReturnUser =
-      (isSubmitted && submittedReview) || (!isSubmitted && !submittedReview)
-    if (shouldReturnUser) return UserModel.find(inv.userId)
-  })
-  let reviewers = await Promise.all(reviewerPromises)
-  reviewers = reviewers.filter(Boolean)
-  const subject = isSubmitted
-    ? `${collection.customId}: Manuscript Decision`
-    : `${collection.customId}: Manuscript ${getSubject(recommendation)}`
-  let emailType = 'agreed-reviewers-after-recommendation'
-  let emailText
-  if (isSubmitted) {
-    emailType = 'submitting-reviewers-after-decision'
-    emailText = 'has now been rejected'
-    if (recommendation === 'publish') emailText = 'will now be published'
-  }
-
-  const eic = await getEditorInChief(UserModel)
-  const editorName = isSubmitted
-    ? `${eic.firstName} ${eic.lastName}`
-    : collection.handlingEditor.name
-  reviewers.forEach(user =>
-    mailService.sendNotificationEmail({
-      toEmail: user.email,
-      emailType,
-      meta: {
-        fragment: { title, authorName },
-        editorName,
-        emailSubject: subject,
-        reviewerName: `${user.firstName} ${user.lastName}`,
-        emailText,
-      },
-    }),
-  )
-}
-
-const setupNoResponseReviewersEmailData = async ({
-  baseUrl,
-  fragment: { title, authorName, type },
-  collection,
-  UserModel,
-}) => {
-  const invitations = collection.invitations.filter(
-    inv => inv.role === 'reviewer' && inv.hasAnswer === false,
-  )
-  const userPromises = await invitations.map(async inv =>
-    UserModel.find(inv.userId),
-  )
-  let users = await Promise.all(userPromises)
-  users = users.filter(Boolean)
-  const subject = `${collection.customId}: Reviewer Unassigned`
-  const manuscriptType = manuscriptTypes[type]
-  users.forEach(user =>
-    mailService.sendNotificationEmail({
-      toEmail: user.email,
-      user,
-      emailType: 'no-response-reviewers-after-recommendation',
-      meta: {
-        collection: { customId: collection.customId },
-        fragment: { title, authorName },
-        handlingEditorName: collection.handlingEditor.name,
-        baseUrl,
-        emailSubject: subject,
-        manuscriptType,
-      },
-    }),
-  )
-}
-
-const setupEiCRecommendationEmailData = async ({
-  baseUrl,
-  UserModel,
-  fragment: { id, title, authorName },
-  collection,
-  recommendation,
-  comments,
-}) => {
-  // to do: get private note from recommendation
-  const privateNote = comments.find(comm => comm.public === false)
-  const content = get(privateNote, 'content')
-  const privateNoteText =
-    content !== undefined ? `Private note: "${content}"` : ''
-  let paragraph
-  const heRecommendation = getHeRecommendation(recommendation)
-  switch (heRecommendation) {
-    case 'publish':
-      paragraph = `It is my recommendation, based on the reviews I have received for the manuscript titled "${title}" by ${authorName}, that we should proceed to publication. <br/><br/>
-      ${privateNoteText}<br/><br/>`
-      break
-    case 'reject':
-      paragraph = `It is my recommendation, based on the reviews I have received for the manuscript titled "${title}" by ${authorName}, that we should reject it for publication. <br/><br/>
-      ${privateNoteText}<br/><br/>`
-      break
-    case 'revision':
-      paragraph = `In order for the manuscript titled "${title}" by ${authorName} to proceed to publication, there needs to be a revision. <br/><br/>
-      ${privateNoteText}<br/><br/>`
-      break
-
-    default:
-      throw new Error('undefined he recommentation type')
-  }
-
-  const eic = await getEditorInChief(UserModel)
-  const toEmail = eic.email
-  await mailService.sendNotificationEmail({
-    toEmail,
-    emailType: 'eic-recommendation',
-    meta: {
-      collection: { customId: collection.customId, id: collection.id },
-      fragment: { id },
-      handlingEditorName: collection.handlingEditor.name,
-      baseUrl,
-      eicName: `${eic.firstName} ${eic.lastName}`,
-      paragraph,
-    },
-  })
-}
-
-const setupAuthorsEmailData = async ({
-  baseUrl,
-  UserModel,
-  fragment: { id, title, submittingAuthor },
-  collection,
-  comments,
-  requestToRevision = false,
-  publish = false,
-}) => {
-  const authorNote = comments.find(comm => comm.public === true)
-  const content = get(authorNote, 'content')
-  const authorNoteText =
-    content !== undefined ? `Reason & Details: "${content}"` : ''
-  let emailType = requestToRevision
-    ? 'author-request-to-revision'
-    : 'author-manuscript-rejected'
-  if (publish) emailType = 'author-manuscript-published'
-  let toAuthors = []
-  if (emailType === 'author-request-to-revision') {
-    toAuthors.push({
-      email: submittingAuthor.email,
-      name: `${submittingAuthor.firstName} ${submittingAuthor.lastName}`,
-    })
-  } else {
-    toAuthors = collection.authors.map(author => ({
-      email: author.email,
-      name: `${author.firstName} ${author.lastName}`,
-    }))
-  }
-  toAuthors.forEach(toAuthor => {
-    mailService.sendNotificationEmail({
-      toEmail: toAuthor.email,
-      emailType,
-      meta: {
-        collection: { customId: collection.customId, id: collection.id },
-        fragment: {
-          id,
-          title,
-          authorName: toAuthor.name,
-          submittingAuthorName: `${submittingAuthor.firstName} ${
-            submittingAuthor.lastName
-          }`,
-        },
-        handlingEditorName: collection.handlingEditor.name,
-        baseUrl,
-        authorNoteText,
-      },
-    })
-  })
-}
-
-const setupManuscriptDecisionEmailForHe = async ({
-  UserModel,
-  fragment: { title, submittingAuthor },
-  collection: { customId, handlingEditor },
-  publish = false,
-}) => {
-  const eic = await getEditorInChief(UserModel)
-  const toEmail = handlingEditor.email
-  const emailType = publish
-    ? 'he-manuscript-published'
-    : 'he-manuscript-rejected'
-  await mailService.sendNotificationEmail({
-    toEmail,
-    emailType,
-    meta: {
-      emailSubject: `${customId}: Manuscript Decision`,
-      fragment: {
-        title,
-        authorName: `${submittingAuthor.firstName} ${
-          submittingAuthor.lastName
-        }`,
-      },
-      handlingEditorName: handlingEditor.name,
-      eicName: `${eic.firstName} ${eic.lastName}`,
-    },
-  })
-}
-const getSubject = recommendation =>
-  ['minor', 'major'].includes(recommendation)
-    ? 'Revision Requested'
-    : 'Recommendation Submitted'
-
-const getHeRecommendation = recommendation => {
-  let heRecommendation = recommendation === 'reject' ? 'reject' : 'publish'
-  if (['minor', 'major'].includes(recommendation)) {
-    heRecommendation = 'revision'
-  }
-  return heRecommendation
-}
-
-module.exports = {
-  getEditorInChief,
-  setupReviewSubmittedEmailData,
-  setupReviewersEmail,
-  setupEiCRecommendationEmailData,
-  setupAuthorsEmailData,
-  setupNoResponseReviewersEmailData,
-  setupManuscriptDecisionEmailForHe,
-}
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
index 97ee0a9f2362a6ca6665257f9cd4419ea73e172c..e629034244dd04c370ad6fde7d3bbef8797f8bd8 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
@@ -1,7 +1,7 @@
 const helpers = require('../../helpers/helpers')
 const authsomeHelper = require('../../helpers/authsome')
 const collectionHelper = require('../../helpers/Collection')
-const userHelper = require('../../helpers/User')
+const Email = require('../../helpers/Email')
 
 module.exports = models => async (req, res) => {
   const { collectionId, fragmentId, recommendationId } = req.params
@@ -17,7 +17,8 @@ module.exports = models => async (req, res) => {
       collection,
       path: req.route.path,
     }
-    const user = await models.User.find(req.user)
+    const UserModel = models.User
+    const user = await UserModel.find(req.user)
     const canPatch = await authsome.can(req.user, 'PATCH', target)
     if (!canPatch)
       return res.status(403).json({
@@ -35,24 +36,29 @@ module.exports = models => async (req, res) => {
       })
     Object.assign(recommendation, req.body)
     recommendation.updatedOn = Date.now()
-    if (req.body.submittedOn !== undefined) {
-      const {
-        title,
-        submittingAuthor,
-      } = await collectionHelper.getFragmentAndAuthorData({
-        UserModel: models.User,
+    if (req.body.submittedOn) {
+      const parsedFragment = await collectionHelper.getFragmentData({
         fragment,
-        collection,
+        handlingEditor: collection.handlingEditor,
+      })
+      const baseUrl = helpers.getBaseUrl(req)
+      const authors = await collectionHelper.getAuthorData({
+        authors: collection.authors,
+        UserModel,
       })
-      await userHelper.setupReviewSubmittedEmailData({
-        baseUrl: helpers.getBaseUrl(req),
-        UserModel: models.User,
-        fragment: { id: fragment.id, title, submittingAuthor },
+      const email = new Email({
+        UserModel,
         collection,
-        user,
+        parsedFragment,
+        baseUrl,
+        authors,
+      })
+      email.setupHandlingEditorEmail({
+        reviewSubmitted: true,
+        reviewerName: `${user.firstName} ${user.lastName}`,
       })
       if (!['pendingApproval', 'revisionRequested'].includes(collection.status))
-        await collectionHelper.updateStatus(collection, 'reviewCompleted')
+        collectionHelper.updateStatus(collection, 'reviewCompleted')
     }
     await fragment.save()
     return res.status(200).json(recommendation)
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
index f00c899edcddaf3339814de655fbc1d83246acc7..c56ec1408a965228941ae92a2bf0dec22fe23729 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
@@ -1,9 +1,9 @@
-const helpers = require('../../helpers/helpers')
 const uuid = require('uuid')
+
+const helpers = require('../../helpers/helpers')
+const Email = require('../../helpers/Email')
 const authsomeHelper = require('../../helpers/authsome')
 const collectionHelper = require('../../helpers/Collection')
-const userHelper = require('../../helpers/User')
-const get = require('lodash/get')
 
 module.exports = models => async (req, res) => {
   const { recommendation, comments, recommendationType } = req.body
@@ -51,98 +51,61 @@ module.exports = models => async (req, res) => {
   newRecommendation.recommendation = recommendation || undefined
   newRecommendation.comments = comments || undefined
   const UserModel = models.User
-
-  const {
-    title,
-    submittingAuthor,
-    type,
-    heRecommendation,
-  } = await collectionHelper.getFragmentAndAuthorData({
-    UserModel,
+  const parsedFragment = await collectionHelper.getFragmentData({
     fragment,
-    collection,
+    handlingEditor: collection.handlingEditor,
   })
   const baseUrl = helpers.getBaseUrl(req)
-  const authorName = `${submittingAuthor.firstName} ${
-    submittingAuthor.lastName
-  }`
+  const authors = await collectionHelper.getAuthorData({
+    authors: collection.authors,
+    UserModel,
+  })
+  const email = new Email({
+    UserModel,
+    collection,
+    parsedFragment,
+    baseUrl,
+    authors,
+  })
+
   if (reqUser.editorInChief || reqUser.admin) {
     if (recommendation === 'return-to-handling-editor')
-      await collectionHelper.updateStatus(collection, 'reviewCompleted')
+      collectionHelper.updateStatus(collection, 'reviewCompleted')
     else {
-      await collectionHelper.updateFinalStatusByRecommendation(
+      collectionHelper.updateFinalStatusByRecommendation(
         collection,
         recommendation,
       )
-      await userHelper.setupAuthorsEmailData({
-        baseUrl,
-        UserModel,
-        collection,
-        fragment: { title, submittingAuthor },
-        comments: get(heRecommendation, 'comments'),
+      email.setupAuthorsEmail({
         requestToRevision: false,
         publish: recommendation === 'publish',
       })
-      await userHelper.setupManuscriptDecisionEmailForHe({
-        UserModel,
-        fragment: { title, submittingAuthor },
-        collection: {
-          customId: collection.customId,
-          handlingEditor: collection.handlingEditor,
-        },
+      email.setupHandlingEditorEmail({
         publish: recommendation === 'publish',
       })
-
-      await userHelper.setupReviewersEmail({
-        UserModel,
-        collection,
-        fragment: {
-          title,
-          authorName,
-          recommendations: fragment.recommendations,
-        },
+      email.parsedFragment.recommendations = fragment.recommendations
+      email.setupReviewersEmail({
         recommendation,
         isSubmitted: true,
       })
     }
   } else if (recommendationType === 'editorRecommendation') {
-    await collectionHelper.updateStatusByRecommendation(
-      collection,
+    collectionHelper.updateStatusByRecommendation(collection, recommendation)
+    email.setupReviewersEmail({
       recommendation,
-    )
-    await userHelper.setupReviewersEmail({
-      UserModel,
-      collection,
-      fragment: {
-        title,
-        authorName,
-        recommendations: fragment.recommendations,
-      },
-      recommendation,
-    })
-    await userHelper.setupNoResponseReviewersEmailData({
-      baseUrl,
-      UserModel,
-      collection,
-      fragment: { title, authorName, type },
+      agree: true,
     })
-    await userHelper.setupEiCRecommendationEmailData({
-      baseUrl,
-      UserModel,
-      collection,
+    email.setupReviewersEmail({ agree: false })
+    email.setupEiCEmail({
       recommendation,
-      fragment: { title, id: fragment.id, authorName },
       comments: newRecommendation.comments,
     })
-    if (['minor', 'major'].includes(recommendation))
-      await userHelper.setupAuthorsEmailData({
-        baseUrl,
-        UserModel,
-        collection,
-        fragment: { title, id: fragment.id, submittingAuthor },
-        comments: newRecommendation.comments,
+    if (['minor', 'major'].includes(recommendation)) {
+      email.parsedFragment.newComments = newRecommendation.comments
+      email.setupAuthorsEmail({
         requestToRevision: true,
       })
+    }
   }
 
   fragment.recommendations.push(newRecommendation)