diff --git a/packages/component-faraday-ui/src/ReviewersTable.js b/packages/component-faraday-ui/src/ReviewersTable.js
index 9f9e2aaa75309afd25084e94a65cbcf65e2c646b..e2197d20c406eeff827b6b4051f48062d7e7493e 100644
--- a/packages/component-faraday-ui/src/ReviewersTable.js
+++ b/packages/component-faraday-ui/src/ReviewersTable.js
@@ -41,9 +41,9 @@ const ReviewersTable = ({
                 invitation,
                 'person.lastName',
               )}`}</Text>
-              {invitation.isAccepted && (
+              {invitation.reviewerNumber && (
                 <Text customId ml={1}>
-                  {renderAcceptedLabel(index)}
+                  Reviewer {invitation.reviewerNumber}
                 </Text>
               )}
             </td>
@@ -102,12 +102,7 @@ export default compose(
   withProps(({ invitations = [] }) => ({
     invitations: orderBy(invitations, orderInvitations),
   })),
-  withProps(({ invitations = [] }) => ({
-    firstAccepted: invitations.findIndex(i => i.hasAnswer && i.isAccepted),
-  })),
   withHandlers({
-    renderAcceptedLabel: ({ firstAccepted, invitations }) => index =>
-      `Reviewer ${index - firstAccepted + 1}`,
     getInvitationStatus: () => ({ hasAnswer, isAccepted }) => {
       if (!hasAnswer) return 'PENDING'
       if (isAccepted) return 'ACCEPTED'
diff --git a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
index d8a41b821abe0639bbb6f9cfbe6ffe17b9f75189..d1a9cbcffcb1e50ee2f2eda2aab33b283e9a8557 100644
--- a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
+++ b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
@@ -13,6 +13,7 @@ import {
   ContextualBox,
   ReviewersTable,
   PublonsTable,
+  indexReviewers,
   ReviewerReport,
   InviteReviewers,
   ReviewerBreakdown,
@@ -118,14 +119,14 @@ const ReviewerDetails = ({
                 {reports.length === 0 && (
                   <Text align="center">No reports submitted yet.</Text>
                 )}
-                {reports.map((report, index) => (
+                {reports.map(report => (
                   <ReviewerReport
                     journal={journal}
                     key={report.id}
                     onDownload={downloadFile}
                     onPreview={previewFile}
                     report={report}
-                    reviewerIndex={index + 1}
+                    reviewerIndex={report.reviewerNumber}
                     showOwner
                   />
                 ))}
@@ -154,7 +155,10 @@ export default compose(
         ...i,
         review: reviewerReports.find(r => r.userId === i.userId),
       })),
-      reports: reviewerReports.filter(r => r.submittedOn),
+      reports: indexReviewers(
+        reviewerReports.filter(r => r.submittedOn),
+        invitations,
+      ),
     }),
   ),
   withProps(({ currentUser }) => ({
diff --git a/packages/component-faraday-ui/src/helpers/utils.js b/packages/component-faraday-ui/src/helpers/utils.js
index 898fd3ebc62282763a1331fd359f9d8da85a732c..8b798e34e7b73272c922ab6201019b5b4b221fb9 100644
--- a/packages/component-faraday-ui/src/helpers/utils.js
+++ b/packages/component-faraday-ui/src/helpers/utils.js
@@ -1,4 +1,4 @@
-import { get, chain } from 'lodash'
+import { get, chain, find } from 'lodash'
 
 export const handleError = fn => e => {
   fn(get(JSON.parse(e.response), 'error', 'Oops! Something went wrong!'))
@@ -10,3 +10,14 @@ export const getReportComments = ({ report, isPublic = false }) =>
     .find(c => c.public === isPublic)
     .get('content')
     .value()
+
+export const indexReviewers = (reports = [], invitations = []) => {
+  reports.forEach(report => {
+    report.reviewerNumber = get(
+      find(invitations, ['userId', report.userId]),
+      'reviewerNumber',
+      0,
+    )
+  })
+  return reports
+}
diff --git a/packages/component-fixture-manager/src/fixtures/collectionIDs.js b/packages/component-fixture-manager/src/fixtures/collectionIDs.js
index e66bb71a232758a7de0746033ba2493745157250..a964c2c498c452599e68dd3457a24eac4c0a3b49 100644
--- a/packages/component-fixture-manager/src/fixtures/collectionIDs.js
+++ b/packages/component-fixture-manager/src/fixtures/collectionIDs.js
@@ -7,5 +7,6 @@ module.exports = {
   collectionReviewCompletedID: chance.guid(),
   collectionNoInvitesID: chance.guid(),
   twoVersionsCollectionId: chance.guid(),
+  oneReviewedFragmentCollectionID: chance.guid(),
   noEditorRecomedationCollectionID: chance.guid(),
 }
diff --git a/packages/component-fixture-manager/src/fixtures/collections.js b/packages/component-fixture-manager/src/fixtures/collections.js
index 7d1df81e4f6379f9bb4d21bc243a2ed97a9e9e2d..0fbff658ca84fc9266a31674461679e769a1ff13 100644
--- a/packages/component-fixture-manager/src/fixtures/collections.js
+++ b/packages/component-fixture-manager/src/fixtures/collections.js
@@ -17,6 +17,7 @@ const {
   collectionReviewCompletedID,
   collectionNoInvitesID,
   twoVersionsCollectionId,
+  oneReviewedFragmentCollectionID,
   noEditorRecomedationCollectionID,
 } = require('./collectionIDs')
 
@@ -30,6 +31,7 @@ const collections = {
     fragments: [fragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [fragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -73,6 +75,7 @@ const collections = {
     fragments: [fragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [fragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -115,6 +118,7 @@ const collections = {
     fragments: [fragment1.id, noInvitesFragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection2),
+    getFragments: jest.fn(() => [fragment1, noInvitesFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -159,6 +163,7 @@ const collections = {
     created: chance.timestamp(),
     customId: '0000001',
     fragments: [reviewCompletedFragment.id],
+    getFragments: jest.fn(() => [reviewCompletedFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -189,6 +194,7 @@ const collections = {
     fragments: [fragment.id, reviewCompletedFragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [fragment, reviewCompletedFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -219,6 +225,7 @@ const collections = {
     fragments: [],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => []),
     customId: chance.natural({ min: 999999, max: 9999999 }),
   },
   noEditorRecomedationCollection: {
@@ -228,6 +235,7 @@ const collections = {
     fragments: [noEditorRecomedationFragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.noEditorRecomedationCollection),
+    getFragments: jest.fn(() => [noEditorRecomedationFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -263,6 +271,37 @@ const collections = {
     },
     status: 'reviewCompleted',
   },
+  oneReviewedFragmentCollection: {
+    id: oneReviewedFragmentCollectionID,
+    title: chance.sentence(),
+    type: 'collection',
+    fragments: [reviewCompletedFragment.id, noInvitesFragment.id],
+    owners: [user.id],
+    save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [reviewCompletedFragment, noInvitesFragment]),
+    invitations: [
+      {
+        id: chance.guid(),
+        role: 'handlingEditor',
+        hasAnswer: true,
+        isAccepted: false,
+        userId: handlingEditor.id,
+        invitedOn: chance.timestamp(),
+        respondedOn: null,
+      },
+    ],
+    handlingEditor: {
+      id: handlingEditor.id,
+      hasAnswer: false,
+      isAccepted: false,
+      email: handlingEditor.email,
+      invitedOn: chance.timestamp(),
+      respondedOn: null,
+      name: `${handlingEditor.firstName} ${handlingEditor.lastName}`,
+    },
+    status: 'revisionRequested',
+    customId: chance.natural({ min: 999999, max: 9999999 }),
+  },
 }
 
 module.exports = collections
diff --git a/packages/component-fixture-manager/src/fixtures/fragments.js b/packages/component-fixture-manager/src/fixtures/fragments.js
index e61b8b432acfb7dfda7254189f0fd7861135ae45..337c0d943c7e6fd87e47fd3e31ff3458c0fb567d 100644
--- a/packages/component-fixture-manager/src/fixtures/fragments.js
+++ b/packages/component-fixture-manager/src/fixtures/fragments.js
@@ -99,6 +99,69 @@ const fragments = {
         createdOn: chance.timestamp(),
         updatedOn: chance.timestamp(),
       },
+      {
+        recommendation: 'publish',
+        recommendationType: 'editorRecommendation',
+        comments: [
+          {
+            content: chance.paragraph(),
+            public: true,
+            files: [
+              {
+                id: chance.guid(),
+                name: 'file.pdf',
+                size: chance.natural(),
+              },
+            ],
+          },
+        ],
+        id: chance.guid(),
+        userId: handlingEditor.id,
+        createdOn: 1542361074012,
+        updatedOn: chance.timestamp(),
+      },
+      {
+        recommendation: 'return-to-handling-editor',
+        recommendationType: 'editorRecommendation',
+        comments: [
+          {
+            content: chance.paragraph(),
+            public: true,
+            files: [
+              {
+                id: chance.guid(),
+                name: 'file.pdf',
+                size: chance.natural(),
+              },
+            ],
+          },
+        ],
+        id: chance.guid(),
+        userId: admin.id,
+        createdOn: 1542361115749,
+        updatedOn: chance.timestamp(),
+      },
+      {
+        recommendation: 'publish',
+        recommendationType: 'editorRecommendation',
+        comments: [
+          {
+            content: chance.paragraph(),
+            public: chance.bool(),
+            files: [
+              {
+                id: chance.guid(),
+                name: 'file.pdf',
+                size: chance.natural(),
+              },
+            ],
+          },
+        ],
+        id: chance.guid(),
+        userId: handlingEditor.id,
+        createdOn: 1542361115750,
+        updatedOn: chance.timestamp(),
+      },
       {
         recommendation: 'publish',
         recommendationType: 'editorRecommendation',
@@ -117,7 +180,7 @@ const fragments = {
         ],
         id: chance.guid(),
         userId: admin.id,
-        createdOn: chance.timestamp(),
+        createdOn: 1542361115751,
         updatedOn: chance.timestamp(),
       },
     ],
@@ -277,6 +340,7 @@ const fragments = {
         invitedOn: chance.timestamp(),
         isAccepted: true,
         respondedOn: chance.timestamp(),
+        reviewerNumber: 2,
       },
       {
         id: chance.guid(),
@@ -457,6 +521,48 @@ const fragments = {
         updatedOn: chance.timestamp(),
         submittedOn: chance.timestamp(),
       },
+      {
+        recommendation: 'publish',
+        recommendationType: 'editorRecommendation',
+        comments: [
+          {
+            content: chance.paragraph(),
+            public: true,
+            files: [
+              {
+                id: chance.guid(),
+                name: 'file.pdf',
+                size: chance.natural(),
+              },
+            ],
+          },
+        ],
+        id: chance.guid(),
+        userId: handlingEditor.id,
+        createdOn: 1542361074012,
+        updatedOn: chance.timestamp(),
+      },
+      {
+        recommendation: 'return-to-handling-editor',
+        recommendationType: 'editorRecommendation',
+        comments: [
+          {
+            content: chance.paragraph(),
+            public: true,
+            files: [
+              {
+                id: chance.guid(),
+                name: 'file.pdf',
+                size: chance.natural(),
+              },
+            ],
+          },
+        ],
+        id: chance.guid(),
+        userId: admin.id,
+        createdOn: 1542361115749,
+        updatedOn: chance.timestamp(),
+      },
     ],
     authors: [
       {
@@ -490,17 +596,9 @@ fragments.noInvitesFragment = {
   invites: [],
   id: chance.guid(),
 }
-fragments.noInvitesFragment = {
-  ...fragments.fragment1,
-  recommendations: [],
-  invites: [],
-  id: chance.guid(),
-}
-
 fragments.noInvitesFragment1 = {
   ...fragments.fragment,
   recommendations: [],
-  invites: [],
   id: chance.guid(),
 }
 fragments.minorRevisionWithoutReview = {
diff --git a/packages/component-helper-service/src/services/Collection.js b/packages/component-helper-service/src/services/Collection.js
index 70efac8ded420595e62bc16fa271b90a74fb741d..0db955323c5e15fe008bf2ef90152788d078df46 100644
--- a/packages/component-helper-service/src/services/Collection.js
+++ b/packages/component-helper-service/src/services/Collection.js
@@ -1,4 +1,4 @@
-const { findLast, get } = require('lodash')
+const { findLast, isEmpty, maxBy, get, flatMap } = require('lodash')
 
 const Fragment = require('./Fragment')
 
@@ -10,6 +10,7 @@ class Collection {
   async updateStatusByRecommendation({
     recommendation,
     isHandlingEditor = false,
+    fragments,
   }) {
     let newStatus
     if (isHandlingEditor) {
@@ -19,7 +20,9 @@ class Collection {
       }
     } else {
       if (recommendation === 'minor') {
-        newStatus = 'reviewCompleted'
+        newStatus = this.hasAtLeastOneReviewReport(fragments)
+          ? 'reviewCompleted'
+          : 'heAssigned'
       }
 
       if (recommendation === 'major') {
@@ -27,7 +30,7 @@ class Collection {
       }
     }
 
-    this.updateStatus({ newStatus })
+    return this.updateStatus({ newStatus })
   }
 
   async updateFinalStatusByRecommendation({ recommendation }) {
@@ -89,18 +92,16 @@ class Collection {
   async updateStatusOnRecommendation({ isEditorInChief, recommendation }) {
     if (isEditorInChief) {
       if (recommendation === 'return-to-handling-editor') {
-        this.updateStatus({ newStatus: 'reviewCompleted' })
-      } else {
-        this.updateFinalStatusByRecommendation({
-          recommendation,
-        })
+        return this.updateStatus({ newStatus: 'reviewCompleted' })
       }
-    } else {
-      this.updateStatusByRecommendation({
+      return this.updateFinalStatusByRecommendation({
         recommendation,
-        isHandlingEditor: true,
       })
     }
+    return this.updateStatusByRecommendation({
+      recommendation,
+      isHandlingEditor: true,
+    })
   }
 
   getHELastName() {
@@ -108,6 +109,27 @@ class Collection {
     return lastName || firstName
   }
 
+  async getReviewerNumber({ userId }) {
+    const allCollectionFragments = await this.collection.getFragments()
+    const allCollectionInvitations = flatMap(
+      allCollectionFragments,
+      fragment => fragment.invitations,
+    )
+    const allNumberedInvitationsForUser = allCollectionInvitations
+      .filter(invite => invite.userId === userId)
+      .filter(invite => invite.reviewerNumber)
+
+    if (isEmpty(allNumberedInvitationsForUser)) {
+      const maxReviewerNumber = get(
+        maxBy(allCollectionInvitations, 'reviewerNumber'),
+        'reviewerNumber',
+        0,
+      )
+      return maxReviewerNumber + 1
+    }
+    return allNumberedInvitationsForUser[0].reviewerNumber
+  }
+
   // eslint-disable-next-line class-methods-use-this
   hasAtLeastOneReviewReport(fragments) {
     return fragments.some(fragment =>
@@ -137,6 +159,14 @@ class Collection {
       return fragmentHelper.hasReviewReport()
     }
   }
+
+  async getAllFragments({ FragmentModel }) {
+    return Promise.all(
+      this.collection.fragments.map(async fragment =>
+        FragmentModel.find(fragment),
+      ),
+    )
+  }
 }
 
 module.exports = Collection
diff --git a/packages/component-helper-service/src/services/Fragment.js b/packages/component-helper-service/src/services/Fragment.js
index ba56f7a41f116f412842fa721f2336cf6430f169..7a0f27ae03d656269c6e5c757c094dd083f1ddb8 100644
--- a/packages/component-helper-service/src/services/Fragment.js
+++ b/packages/component-helper-service/src/services/Fragment.js
@@ -1,4 +1,4 @@
-const { get, remove } = require('lodash')
+const { get, remove, findLast, last } = require('lodash')
 const config = require('config')
 const User = require('./User')
 
@@ -145,11 +145,21 @@ class Fragment {
 
   hasReviewReport() {
     const { fragment: { recommendations = [] } } = this
-    return recommendations.find(
+    return recommendations.some(
       rec => rec.recommendationType === 'review' && rec.submittedOn,
     )
   }
 
+  canHEMakeAnotherRecommendation(currentUserRecommendations) {
+    const lastHERecommendation = last(currentUserRecommendations)
+    const { fragment: { recommendations = [] } } = this
+    const returnToHERecommendation = findLast(
+      recommendations,
+      r => r.recommendation === 'return-to-handling-editor',
+    )
+    if (!returnToHERecommendation) return false
+    return returnToHERecommendation.createdOn > lastHERecommendation.createdOn
+  }
   async getReviewersAndEditorsData({ collection, UserModel }) {
     const {
       invitations = [],
diff --git a/packages/component-helper-service/src/tests/collection.test.js b/packages/component-helper-service/src/tests/collection.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..167153af8c03fc7149c36a9e8c149de351c0f7db
--- /dev/null
+++ b/packages/component-helper-service/src/tests/collection.test.js
@@ -0,0 +1,234 @@
+process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
+process.env.SUPPRESS_NO_CONFIG_WARNING = true
+
+const { cloneDeep } = require('lodash')
+const fixturesService = require('pubsweet-component-fixture-service')
+
+const { fixtures, Model } = fixturesService
+const { Collection, Fragment } = require('../Helper')
+
+describe('Collection helper', () => {
+  let testFixtures = {}
+  let models
+
+  beforeEach(() => {
+    testFixtures = cloneDeep(fixtures)
+    models = Model.build(testFixtures)
+  })
+
+  describe('getReviewerNumber', () => {
+    it('should assign reviewer number 1 on invitation if no other reviewer numbers exist', async () => {
+      const { collection } = testFixtures.collections
+      const { reviewer } = testFixtures.users
+      const collectionHelper = new Collection({ collection })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: reviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(1)
+    })
+    it('should assign next reviewer number on invitation if another reviewer numbers exist', async () => {
+      const { collectionReviewCompleted } = testFixtures.collections
+      const { reviewer } = testFixtures.users
+      const collectionHelper = new Collection({
+        collection: collectionReviewCompleted,
+      })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: reviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(3)
+    })
+    it('should keep reviewer number across fragment versions', async () => {
+      const { oneReviewedFragmentCollection } = testFixtures.collections
+      const { answerReviewer } = testFixtures.users
+      const collectionHelper = new Collection({
+        collection: oneReviewedFragmentCollection,
+      })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: answerReviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(2)
+    })
+    it('should assign next reviewer number across fragment versions', async () => {
+      const { oneReviewedFragmentCollection } = testFixtures.collections
+      const { reviewer } = testFixtures.users
+      const collectionHelper = new Collection({
+        collection: oneReviewedFragmentCollection,
+      })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: reviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(3)
+    })
+  })
+
+  describe('hasAtLeastOneReviewReport', () => {
+    it('should return true if collection has at least one report from reviewers.', async () => {
+      const { collection } = testFixtures.collections
+      const collectionHelper = new Collection({ collection })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const hasReviewReport = await collectionHelper.hasAtLeastOneReviewReport(
+        fragments,
+      )
+      expect(hasReviewReport).toBe(true)
+    })
+    it('should return false if collection has at least one report from reviewers.', async () => {
+      const { noInvitesFragment } = testFixtures.fragments
+      const { collection } = testFixtures.collections
+      collection.fragments = [noInvitesFragment.id]
+      const collectionHelper = new Collection({ collection })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const hasReviewReport = await collectionHelper.hasAtLeastOneReviewReport(
+        fragments,
+      )
+      expect(hasReviewReport).toBe(false)
+    })
+  })
+
+  describe('canHEMakeRecommendation', () => {
+    it('should return true when creating a recommendation as a HE when there is a single version with at least one review.', async () => {
+      const { collection } = testFixtures.collections
+      const { fragment } = testFixtures.fragments
+      const collectionHelper = new Collection({
+        collection,
+      })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const fragmentHelper = new Fragment({ fragment })
+      const canHEMakeRecommendation = await collectionHelper.canHEMakeRecommendation(
+        fragments,
+        fragmentHelper,
+      )
+      expect(canHEMakeRecommendation).toBe(true)
+    })
+    it('should return false when creating a recommendation with publish as a HE when there is a single version and there are no reviews.', async () => {
+      const { collection } = testFixtures.collections
+      const { fragment } = testFixtures.fragments
+      fragment.recommendations = undefined
+
+      const collectionHelper = new Collection({
+        collection,
+      })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const fragmentHelper = new Fragment({ fragment })
+      const canHEMakeRecommendation = await collectionHelper.canHEMakeRecommendation(
+        fragments,
+        fragmentHelper,
+      )
+      expect(canHEMakeRecommendation).toBe(false)
+    })
+    it('should return true when creating a recommendation as a HE after minor revision and we have at least one review on collection.', async () => {
+      const { collection } = testFixtures.collections
+      const {
+        minorRevisionWithReview,
+        noInvitesFragment1,
+      } = testFixtures.fragments
+      collection.fragments = [minorRevisionWithReview.id, noInvitesFragment1.id]
+      const collectionHelper = new Collection({
+        collection,
+      })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const fragmentHelper = new Fragment({ fragment: noInvitesFragment1 })
+
+      const canHEMakeRecommendation = await collectionHelper.canHEMakeRecommendation(
+        fragments,
+        fragmentHelper,
+      )
+      expect(canHEMakeRecommendation).toBe(true)
+    })
+    it('should return false when creating a recommendation as a HE after minor revision and there are no reviews.', async () => {
+      const { collection } = testFixtures.collections
+      const {
+        minorRevisionWithoutReview,
+        noInvitesFragment1,
+      } = testFixtures.fragments
+      collection.fragments = [
+        minorRevisionWithoutReview.id,
+        noInvitesFragment1.id,
+      ]
+
+      const collectionHelper = new Collection({
+        collection,
+      })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const fragmentHelper = new Fragment({ noInvitesFragment1 })
+      const canHEMakeRecommendation = await collectionHelper.canHEMakeRecommendation(
+        fragments,
+        fragmentHelper,
+      )
+      expect(canHEMakeRecommendation).toBe(false)
+    })
+    it('should return true when creating a recommendation as a HE after major revision and there are least one review on fragment.', async () => {
+      const { collection } = testFixtures.collections
+      const {
+        majorRevisionWithReview,
+        reviewCompletedFragment,
+      } = testFixtures.fragments
+
+      reviewCompletedFragment.collectionId = collection.id
+      collection.fragments = [
+        majorRevisionWithReview.id,
+        reviewCompletedFragment.id,
+      ]
+
+      const collectionHelper = new Collection({
+        collection,
+      })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const fragmentHelper = new Fragment({ fragment: reviewCompletedFragment })
+      const canHEMakeRecommendation = await collectionHelper.canHEMakeRecommendation(
+        fragments,
+        fragmentHelper,
+      )
+      expect(canHEMakeRecommendation).toBe(true)
+    })
+    it('should return false when creating a recommendation as a HE after major revision there are no reviews on fragment.', async () => {
+      const { collection } = testFixtures.collections
+      const {
+        majorRevisionWithReview,
+        noInvitesFragment1,
+      } = testFixtures.fragments
+      collection.fragments = [majorRevisionWithReview.id, noInvitesFragment1.id]
+      const collectionHelper = new Collection({
+        collection,
+      })
+      const FragmentModel = models.Fragment
+      const fragments = await collectionHelper.getAllFragments({
+        FragmentModel,
+      })
+      const fragmentHelper = new Fragment({ fragment: noInvitesFragment1 })
+      const canHEMakeRecommendation = await collectionHelper.canHEMakeRecommendation(
+        fragments,
+        fragmentHelper,
+      )
+      expect(canHEMakeRecommendation).toBe(false)
+    })
+  })
+})
diff --git a/packages/component-helper-service/src/tests/fragment.test.js b/packages/component-helper-service/src/tests/fragment.test.js
index 26598cfe8bd73fc40a8966a03ab51aa3552f3668..c5623dc18a8d7cf4812d3695189319f48b7e2202 100644
--- a/packages/component-helper-service/src/tests/fragment.test.js
+++ b/packages/component-helper-service/src/tests/fragment.test.js
@@ -15,6 +15,8 @@ const { recommendations: configRecommendations } = config
 const acceptedReviewerId = chance.guid()
 const submittedReviewerId1 = chance.guid()
 const submittedReviewerId2 = chance.guid()
+const handlingEditorId = chance.guid()
+const editorInChiefId = chance.guid()
 const fragment = {
   invitations: [
     {
@@ -281,4 +283,93 @@ describe('Fragment helper', () => {
       }
     })
   })
+  describe('canHEMakeAnotherRecommendation', () => {
+    it('should return true when He makes a recommendation after EIC decision was to return to HE', async () => {
+      testFragment.recommendations = [
+        {
+          recommendation: 'publish',
+          recommendationType: 'editorRecommendation',
+          comments: [
+            {
+              content: chance.paragraph(),
+              public: true,
+              files: [
+                {
+                  id: chance.guid(),
+                  name: 'file.pdf',
+                  size: chance.natural(),
+                },
+              ],
+            },
+          ],
+          id: chance.guid(),
+          userId: handlingEditorId,
+          createdOn: 1542361074012,
+          updatedOn: chance.timestamp(),
+        },
+        {
+          recommendation: 'return-to-handling-editor',
+          recommendationType: 'editorRecommendation',
+          comments: [
+            {
+              content: chance.paragraph(),
+              public: true,
+              files: [
+                {
+                  id: chance.guid(),
+                  name: 'file.pdf',
+                  size: chance.natural(),
+                },
+              ],
+            },
+          ],
+          id: chance.guid(),
+          userId: editorInChiefId,
+          createdOn: 1542361115749,
+          updatedOn: chance.timestamp(),
+        },
+      ]
+      const currentUserRecommendations = testFragment.recommendations.filter(
+        r => r.userId === handlingEditorId,
+      )
+      const fragmentHelper = new Fragment({ fragment: testFragment })
+      const canHEMakeAnotherRecommendation = await fragmentHelper.canHEMakeAnotherRecommendation(
+        currentUserRecommendations,
+      )
+      expect(canHEMakeAnotherRecommendation).toBe(true)
+    })
+    it('should return false when He makes another recommendation', async () => {
+      testFragment.recommendations = [
+        {
+          recommendation: 'publish',
+          recommendationType: 'editorRecommendation',
+          comments: [
+            {
+              content: chance.paragraph(),
+              public: true,
+              files: [
+                {
+                  id: chance.guid(),
+                  name: 'file.pdf',
+                  size: chance.natural(),
+                },
+              ],
+            },
+          ],
+          id: chance.guid(),
+          userId: handlingEditorId,
+          createdOn: 1542361074012,
+          updatedOn: chance.timestamp(),
+        },
+      ]
+      const currentUserRecommendations = testFragment.recommendations.filter(
+        r => r.userId === handlingEditorId,
+      )
+      const fragmentHelper = new Fragment({ fragment: testFragment })
+      const canHEMakeAnotherRecommendation = await fragmentHelper.canHEMakeAnotherRecommendation(
+        currentUserRecommendations,
+      )
+      expect(canHEMakeAnotherRecommendation).toBe(false)
+    })
+  })
 })
diff --git a/packages/component-invite/src/routes/fragmentsInvitations/post.js b/packages/component-invite/src/routes/fragmentsInvitations/post.js
index 1a441531473daef14c295e408fc86e7d57fed96d..0e45b83faac29aef7b05b2ca588cf07b6dc7fb0e 100644
--- a/packages/component-invite/src/routes/fragmentsInvitations/post.js
+++ b/packages/component-invite/src/routes/fragmentsInvitations/post.js
@@ -4,6 +4,7 @@ const {
   services,
   Collection,
   Invitation,
+  Fragment,
   authsome: authsomeHelper,
 } = require('pubsweet-component-helper-service')
 
@@ -116,7 +117,12 @@ module.exports = models => async (req, res) => {
       })
     }
 
-    if (collection.status === 'heAssigned') {
+    const fragmentHelper = new Fragment({ fragment })
+    if (
+      collection.status === 'heAssigned' ||
+      (collection.status === 'reviewCompleted' &&
+        !fragmentHelper.hasReviewReport())
+    ) {
       collectionHelper.updateStatus({ newStatus: 'reviewersInvited' })
     }
 
diff --git a/packages/component-manuscript-manager/src/routes/fragments/patch.js b/packages/component-manuscript-manager/src/routes/fragments/patch.js
index 396672ff07542005238642045ebe226e45d8fa3c..acd037254ddb9ada6417d99980a2a30588799d08 100644
--- a/packages/component-manuscript-manager/src/routes/fragments/patch.js
+++ b/packages/component-manuscript-manager/src/routes/fragments/patch.js
@@ -103,8 +103,13 @@ module.exports = models => async (req, res) => {
       await authorsTeam.save()
     }
 
-    collectionHelper.updateStatusByRecommendation({
+    const fragments = await collectionHelper.getAllFragments({
+      FragmentModel: models.Fragment,
+    })
+
+    await collectionHelper.updateStatusByRecommendation({
       recommendation: heRecommendation.recommendation,
+      fragments,
     })
 
     newFragment.submitted = Date.now()
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
index 7846722ed2f83db255a59ff80f95c142ccf2d3ec..7cd5b2ae49984d23fff26a53ae1bfb38a19f8244 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
@@ -1,3 +1,4 @@
+const { find } = require('lodash')
 const {
   services,
   authsome: authsomeHelper,
@@ -8,6 +9,7 @@ const Notification = require('../../notifications/notification')
 
 module.exports = models => async (req, res) => {
   const { collectionId, fragmentId, recommendationId } = req.params
+  const userId = req.user
   let collection, fragment
   try {
     collection = await models.Collection.find(collectionId)
@@ -25,7 +27,7 @@ module.exports = models => async (req, res) => {
     if (!recommendation)
       return res.status(404).json({ error: 'Recommendation not found.' })
 
-    if (recommendation.userId !== req.user)
+    if (recommendation.userId !== userId)
       return res.status(403).json({
         error: 'Unauthorized.',
       })
@@ -35,14 +37,14 @@ module.exports = models => async (req, res) => {
       fragment,
       path: req.route.path,
     }
-    const canPatch = await authsome.can(req.user, 'PATCH', target)
+    const canPatch = await authsome.can(userId, 'PATCH', target)
     if (!canPatch)
       return res.status(403).json({
         error: 'Unauthorized.',
       })
 
     const UserModel = models.User
-    const reviewer = await UserModel.find(req.user)
+    const reviewer = await UserModel.find(userId)
 
     Object.assign(recommendation, req.body)
     recommendation.updatedOn = Date.now()
@@ -62,6 +64,16 @@ module.exports = models => async (req, res) => {
         const collectionHelper = new Collection({ collection })
         collectionHelper.updateStatus({ newStatus: 'reviewCompleted' })
       }
+
+      const collectionHelper = new Collection({ collection })
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId,
+      })
+
+      find(fragment.invitations, [
+        'userId',
+        userId,
+      ]).reviewerNumber = reviewerNumber
     }
 
     fragment.save()
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
index db2336e8eebebb019f2eecf603381fa7973a5b6e..b47234c1f1a017149269ba6e415ee49d5af6b159 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
@@ -1,6 +1,5 @@
-/* eslint-disable no-return-await */
 const uuid = require('uuid')
-const { pick, get, set, has, isEmpty, last } = require('lodash')
+const { pick, get, set, has, isEmpty, last, chain } = require('lodash')
 const config = require('config')
 const { v4 } = require('uuid')
 const logger = require('@pubsweet/logger')
@@ -45,11 +44,9 @@ module.exports = models => async (req, res) => {
   const collectionHelper = new Collection({ collection })
 
   try {
-    fragments = await Promise.all(
-      collection.fragments.map(
-        async fragment => await models.Fragment.find(fragment),
-      ),
-    )
+    fragments = await collectionHelper.getAllFragments({
+      FragmentModel: models.Fragment,
+    })
   } catch (e) {
     const notFoundError = await services.handleNotFoundError(e, 'Item')
     fragments = []
@@ -57,9 +54,16 @@ module.exports = models => async (req, res) => {
       error: notFoundError.message,
     })
   }
-  const currentUserRecommendation = get(fragment, 'recommendations', []).filter(
-    r => r.userId === req.user,
-  )
+  const currentUserRecommendations = get(
+    fragment,
+    'recommendations',
+    [],
+  ).filter(r => r.userId === req.user)
+
+  const lastFragmentRecommendation = chain(fragment)
+    .get('recommendations', [])
+    .last()
+    .value()
 
   const authsome = authsomeHelper.getAuthsome(models)
   const target = {
@@ -92,16 +96,32 @@ module.exports = models => async (req, res) => {
   }
   if (
     last(collection.fragments) === fragmentId &&
-    !isEmpty(currentUserRecommendation)
+    !isEmpty(currentUserRecommendations)
   ) {
     if (recommendationType === recommendations.type.review) {
       return res
         .status(400)
         .json({ error: 'Cannot write another review on this version.' })
     }
-    return res
-      .status(400)
-      .json({ error: 'Cannot make another recommendation on this version.' })
+    if (
+      recommendationType === recommendations.type.editor &&
+      !isEditorInChief &&
+      !fragmentHelper.canHEMakeAnotherRecommendation(currentUserRecommendations)
+    ) {
+      return res.status(400).json({
+        error: 'Cannot make another recommendation on this version.',
+      })
+    }
+    if (
+      recommendationType === recommendations.type.editor &&
+      isEditorInChief &&
+      recommendation !== recommendations.reject &&
+      lastFragmentRecommendation.recommendation === 'return-to-handling-editor'
+    ) {
+      return res.status(400).json({
+        error: 'Cannot make another recommendation on this version.',
+      })
+    }
   }
 
   if (
@@ -130,7 +150,7 @@ module.exports = models => async (req, res) => {
   newRecommendation.comments = comments || undefined
 
   if (recommendationType === 'editorRecommendation') {
-    collectionHelper.updateStatusOnRecommendation({
+    await collectionHelper.updateStatusOnRecommendation({
       isEditorInChief,
       recommendation,
     })
diff --git a/packages/component-manuscript-manager/src/tests/collections/get.test.js b/packages/component-manuscript-manager/src/tests/collections/get.test.js
index fb88e5658444b5c3bad2f2cf5ac7760bf9900537..aa4a1cfec4a3e9de92809e07e056a81b2aaede1f 100644
--- a/packages/component-manuscript-manager/src/tests/collections/get.test.js
+++ b/packages/component-manuscript-manager/src/tests/collections/get.test.js
@@ -61,7 +61,7 @@ describe('Get collections route handler', () => {
 
     expect(data).toHaveLength(2)
     expect(data[0].type).toEqual('collection')
-    expect(data[0].currentVersion.recommendations).toHaveLength(3)
+    expect(data[0].currentVersion.recommendations).toHaveLength(6)
     expect(data[0].currentVersion.authors[0]).not.toHaveProperty('email')
   })
 
diff --git a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
index df52effe144daf17b1a9ec16e546c4f189b62187..5638eb69ff3be3a1a164b0226377f6c38d7f0486 100644
--- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
+++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
@@ -571,6 +571,52 @@ describe('Post fragments recommendations route handler', () => {
     expect(data.error).toEqual('Cannot write another review on this version.')
   })
 
+  it('should return success when creating another recommendation as a HE on the same version when EiC returned manuscript to He ', async () => {
+    const { noRecommendationHE } = testFixtures.users
+    const { noEditorRecomedationCollection } = testFixtures.collections
+    const { noEditorRecomedationFragment } = testFixtures.fragments
+
+    const res = await requests.sendRequest({
+      body,
+      userId: noRecommendationHE.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: noEditorRecomedationCollection.id,
+        fragmentId: noEditorRecomedationFragment.id,
+      },
+    })
+    expect(res.statusCode).toBe(200)
+    const data = JSON.parse(res._getData())
+    expect(data.userId).toEqual(noRecommendationHE.id)
+  })
+
+  it('should return an error when creating another recommendation as a HE on the same version after EiC made decision to publish', async () => {
+    const { handlingEditor } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    body.recommendation = 'publish'
+    body.recommendationType = 'editorRecommendation'
+
+    const res = await requests.sendRequest({
+      body,
+      userId: handlingEditor.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+    expect(res.statusCode).toBe(400)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual(
+      'Cannot make another recommendation on this version.',
+    )
+  })
+
   it('should return an error when an EiC makes a decision on an older version of a manuscript', async () => {
     const { editorInChief } = testFixtures.users
     const { twoVersionsCollection } = testFixtures.collections