Newer
Older
Sebastian Mihalache
committed
const {
Sebastian Mihalache
committed
services,
Collection,
Invitation,
Sebastian Mihalache
committed
} = require('pubsweet-component-helper-service')

Sebastian Mihalache
committed
const Job = require('pubsweet-component-jobs')
Sebastian Mihalache
committed
const notifications = require('./emails/notifications')
Sebastian Mihalache
committed
module.exports = models => async (req, res) => {
const { collectionId, invitationId, fragmentId } = req.params
const { isAccepted, reason } = req.body
const UserModel = models.User
const user = await UserModel.find(req.user)
Sebastian Mihalache
committed
try {
const collection = await models.Collection.find(collectionId)
if (!collection.fragments.includes(fragmentId))
return res.status(400).json({
error: `Fragment ${fragmentId} does not match collection ${collectionId}`,
})
Sebastian Mihalache
committed
Sebastian Mihalache
committed
const fragment = await models.Fragment.find(fragmentId)
Sebastian Mihalache
committed
Sebastian Mihalache
committed
fragment.invitations = fragment.invitations || []
const invitation = await fragment.invitations.find(
invitation => invitation.id === invitationId,
)
const invitationHelper = new Invitation({
userId: user.id,
role: 'reviewer',
invitation,
})
Sebastian Mihalache
committed
const invitationValidation = invitationHelper.validateInvitation()
Sebastian Mihalache
committed
if (invitationValidation.error)
return res.status(invitationValidation.status).json({
error: invitationValidation.error,
})
const authsome = authsomeHelper.getAuthsome(models)
const canPatch = await authsome.can(req.user, 'PATCH', invitation)
if (!canPatch)
return res.status(403).json({
error: 'Unauthorized.',
})

Sebastian Mihalache
committed
await Job.cancelQueue(`reminders-${user.id}-${invitation.id}`)
await Job.cancelQueue(`removal-${user.id}-${invitation.id}`)
Sebastian Mihalache
committed
const collectionHelper = new Collection({ collection })
const baseUrl = services.getBaseUrl(req)
invitation.respondedOn = Date.now()
invitation.hasAnswer = true
Sebastian Mihalache
committed
invitation.isAccepted = isAccepted
Sebastian Mihalache
committed
if (isAccepted) {
Sebastian Mihalache
committed
if (collection.status === 'reviewersInvited') {
collectionHelper.updateStatus({ newStatus: 'underReview' })
}
fragment.save()
} else {
if (reason) invitation.reason = reason
Sebastian Mihalache
committed
await fragment.save()
Sebastian Mihalache
committed
collectionHelper.updateStatusByNumberOfReviewers({
invitations: fragment.invitations,
Sebastian Mihalache
committed
})
const teamHelper = new Team({
fragmentId,
collectionId,
TeamModel: models.Team,
})
const reviewerTeam = await teamHelper.getTeam({
role: 'reviewer',
objectType: 'fragment',
})
await teamHelper.removeTeamMember({
teamId: reviewerTeam.id,
userId: user.id,
})
user.teams = user.teams.filter(
userTeamId => reviewerTeam.id !== userTeamId,
)
await user.save()
Sebastian Mihalache
committed
}
notifications.sendHandlingEditorEmail({
Sebastian Mihalache
committed
baseUrl,
fragment,
collection,
reviewer: user,
UserModel: models.User,
emailType:
isAccepted === true ? 'reviewer-accepted' : 'reviewer-declined',
Sebastian Mihalache
committed
})
if (isAccepted) {
notifications.sendReviewerEmail({
baseUrl,
fragment,
collection,
reviewer: user,
isCanceled: false,
UserModel: models.User,
})
}
Sebastian Mihalache
committed
return res.status(200).json(invitation)
} catch (e) {
const notFoundError = await services.handleNotFoundError(e, 'Item')
return res.status(notFoundError.status).json({
error: notFoundError.message,
})
}
}