Newer
Older
const { findLast, isEmpty, maxBy, get, flatMap } = require('lodash')
Andrei Cioromila
committed
const Fragment = require('./Fragment')

Mihail Hagiu
committed
class Collection {
constructor({ collection = {} }) {
this.collection = collection
}
async updateStatusByRecommendation({
recommendation,
isHandlingEditor = false,
Andrei Cioromila
committed
fragments,
}) {
let newStatus
if (isHandlingEditor) {
newStatus = 'pendingApproval'
if (['minor', 'major'].includes(recommendation)) {
newStatus = 'revisionRequested'
}
} else {
if (recommendation === 'minor') {
Andrei Cioromila
committed
newStatus = this.hasAtLeastOneReviewReport(fragments)
? 'reviewCompleted'
: 'heAssigned'
if (recommendation === 'major') {
}
}
return this.updateStatus({ newStatus })
}
async updateFinalStatusByRecommendation({ recommendation }) {
let newStatus
switch (recommendation) {
case 'reject':
newStatus = 'rejected'
break
case 'publish':
newStatus = 'accepted'
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
break
case 'return-to-handling-editor':
newStatus = 'reviewCompleted'
break
default:
break
}
await this.updateStatus({ newStatus })
}
async updateStatus({ newStatus }) {
this.collection.status = newStatus
await this.collection.save()
}
async addHandlingEditor({ user, invitation }) {
this.collection.handlingEditor = {
id: user.id,
name: `${user.firstName} ${user.lastName}`,
invitedOn: invitation.invitedOn,
respondedOn: invitation.respondedOn,
email: user.email,
hasAnswer: invitation.hasAnswer,
isAccepted: invitation.isAccepted,
}
await this.updateStatus({ newStatus: 'heInvited' })
}
async updateHandlingEditor({ isAccepted }) {
const { collection: { handlingEditor } } = this
handlingEditor.hasAnswer = true
handlingEditor.isAccepted = isAccepted
handlingEditor.respondedOn = Date.now()
const newStatus = isAccepted ? 'heAssigned' : 'submitted'
await this.updateStatus({ newStatus })
async updateStatusByNumberOfReviewers({ invitations }) {
const reviewerInvitations = invitations.filter(
inv => inv.role === 'reviewer',
)
if (reviewerInvitations.length === 0)
await this.updateStatus({ newStatus: 'heAssigned' })
}
async updateStatusOnRecommendation({ isEditorInChief, recommendation }) {
if (isEditorInChief) {
if (recommendation === 'return-to-handling-editor') {
Andrei Cioromila
committed
return this.updateStatus({ newStatus: 'reviewCompleted' })
Andrei Cioromila
committed
return this.updateFinalStatusByRecommendation({
Andrei Cioromila
committed
return this.updateStatusByRecommendation({
recommendation,
isHandlingEditor: true,
})
Sebastian Mihalache
committed
getHELastName() {
Sebastian Mihalache
committed
const [firstName, lastName] = this.collection.handlingEditor.name.split(' ')
return lastName || firstName
Sebastian Mihalache
committed
}

Mihail Hagiu
committed
Andrei Cioromila
committed
async getReviewerNumber({ userId }) {
const allCollectionFragments = await this.collection.getFragments()
const allCollectionInvitations = flatMap(
allCollectionFragments,
fragment => fragment.invitations,

Mihail Hagiu
committed
)
const allNumberedInvitationsForUser = allCollectionInvitations

Mihail Hagiu
committed
.filter(invite => invite.userId === userId)

Mihail Hagiu
committed
.filter(invite => invite.reviewerNumber)
if (isEmpty(allNumberedInvitationsForUser)) {
const maxReviewerNumber = get(
maxBy(allCollectionInvitations, 'reviewerNumber'),
'reviewerNumber',
0,
)
return maxReviewerNumber + 1
}

Mihail Hagiu
committed
return allNumberedInvitationsForUser[0].reviewerNumber
}
Andrei Cioromila
committed
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// eslint-disable-next-line class-methods-use-this
hasAtLeastOneReviewReport(fragments) {
return fragments.some(fragment =>
new Fragment({ fragment }).hasReviewReport(),
)
}
canHEMakeRecommendation(fragments, fragmentHelper) {
if (this.collection.fragments.length === 1) {
return fragmentHelper.hasReviewReport()
}
const previousVersionRecommendations = get(
fragments[fragments.length - 2],
'recommendations',
[],
)
const lastRecommendationByHE = findLast(
previousVersionRecommendations,
recommendation =>
recommendation.userId === this.collection.handlingEditor.id &&
recommendation.recommendationType === 'editorRecommendation',
)
if (lastRecommendationByHE.recommendation === 'minor') {
return this.hasAtLeastOneReviewReport(fragments)
} else if (lastRecommendationByHE.recommendation === 'major') {
return fragmentHelper.hasReviewReport()
}
}
Andrei Cioromila
committed
async getAllFragments({ FragmentModel }) {
return Promise.all(
this.collection.fragments.map(async fragment =>
FragmentModel.find(fragment),
),
)
}
}
module.exports = Collection