const { union, omit } = require('lodash') const { Team, services, Fragment, Collection, authsome: authsomeHelper, } = require('pubsweet-component-helper-service') const notifications = require('./notifications/notifications') module.exports = models => async (req, res) => { const { collectionId, fragmentId } = req.params let collection, fragment try { collection = await models.Collection.find(collectionId) if (!collection.fragments.includes(fragmentId)) return res.status(400).json({ error: `Collection and fragment do not match.`, }) fragment = await models.Fragment.find(fragmentId) if (!fragment.revision) { return res.status(400).json({ error: 'No revision has been found.', }) } const authsome = authsomeHelper.getAuthsome(models) const target = { fragment, path: req.route.path, } const canPatch = await authsome.can(req.user, 'PATCH', target) if (!canPatch) return res.status(403).json({ error: 'Unauthorized.', }) const collectionHelper = new Collection({ collection }) const fragmentHelper = new Fragment({ fragment }) const heRecommendation = fragmentHelper.getLatestHERequestToRevision() if (!heRecommendation) { return res.status(400).json({ error: 'No Handling Editor request to revision has been found.', }) } const newFragmentBody = { ...omit(fragment, ['revision', 'recommendations', 'id']), ...fragment.revision, invitations: fragmentHelper.getInvitations({ isAccepted: true, type: 'submitted', }), version: fragment.version + 1, created: new Date(), } let newFragment = new models.Fragment(newFragmentBody) newFragment = await newFragment.save() const teamHelper = new Team({ TeamModel: models.Team, collectionId, fragmentId: newFragment.id, }) delete fragment.revision fragment.save() if (heRecommendation.recommendation === 'major') { const reviewerIds = newFragment.invitations.map(inv => inv.userId) teamHelper.createTeam({ role: 'reviewer', members: reviewerIds, objectType: 'fragment', }) } else { delete newFragment.invitations await newFragment.save() } const authorIds = newFragment.authors.map(auth => { const { id } = auth return id }) let authorsTeam = await teamHelper.getTeam({ role: 'author', objectType: 'fragment', }) if (!authorsTeam) { authorsTeam = await teamHelper.createTeam({ role: 'author', members: authorIds, objectType: 'fragment', }) } else { authorsTeam.members = union(authorsTeam.members, authorIds) await authorsTeam.save() } await collectionHelper.updateStatusByRecommendation({ recommendation: heRecommendation.recommendation, }) newFragment.submitted = Date.now() newFragment = await newFragment.save() collection.fragments.push(newFragment.id) collection.save() notifications.sendHandlingEditorEmail({ baseUrl: services.getBaseUrl(req), fragment: newFragment, UserModel: models.User, collection, }) if (heRecommendation.recommendation === 'major') { notifications.sendReviewersEmail({ baseUrl: services.getBaseUrl(req), fragment: newFragment, UserModel: models.User, collection, previousVersion: fragment, }) } return res.status(200).json(newFragment) } catch (e) { const notFoundError = await services.handleNotFoundError(e, 'Item') return res.status(notFoundError.status).json({ error: notFoundError.message, }) } }