const get = require('lodash/get') const User = require('./User') class Fragment { constructor({ fragment }) { this.fragment = fragment } set _fragment(newFragment) { this.fragment = newFragment } static setFragmentOwners(fragment = {}, author = {}) { const { owners = [] } = fragment if (author.isSubmitting) { const authorAlreadyOwner = owners.includes(author.id) if (!authorAlreadyOwner) { return [author.id, ...owners] } } return owners } async getFragmentData({ handlingEditor } = {}) { const { fragment: { metadata = {}, recommendations = [], id } } = this let heRecommendation if (handlingEditor) { heRecommendation = recommendations.find( rec => rec.userId === handlingEditor.id, ) } let { title = '', abstract = '' } = metadata const { type } = metadata title = title.replace(/<(.|\n)*?>/g, '') abstract = abstract ? abstract.replace(/<(.|\n)*?>/g, '') : '' return { id, type, title, abstract, recommendations, heRecommendation, } } async addAuthor({ user, isSubmitting, isCorresponding }) { const { fragment } = this fragment.authors = fragment.authors || [] const author = { id: user.id, firstName: user.firstName || '', lastName: user.lastName || '', email: user.email, title: user.title || '', affiliation: user.affiliation || '', isSubmitting, isCorresponding, } fragment.authors.push(author) fragment.owners = this.constructor.setFragmentOwners(fragment, author) await fragment.save() return author } async getAuthorData({ UserModel }) { const { fragment: { authors = [] } } = this const submittingAuthorData = authors.find(author => author.isSubmitting) try { const submittingAuthor = await UserModel.find( get(submittingAuthorData, 'id'), ) const userHelper = new User({ UserModel }) const activeAuthors = await userHelper.getActiveAuthors(authors) return { activeAuthors, submittingAuthor, } } catch (e) { throw e } } getInvitations({ isAccepted = true, role = 'reviewer', type }) { const { fragment: { invitations = [], recommendations = [] } } = this let filteredInvitations = isAccepted ? invitations.filter( inv => inv.role === role && inv.hasAnswer === true && inv.isAccepted === true, ) : invitations.filter(inv => inv.role === role && inv.hasAnswer === false) if (type === 'submitted') { filteredInvitations = filteredInvitations.filter(inv => recommendations.find( rec => rec.recommendationType === 'review' && rec.submittedOn && inv.userId === rec.userId, ), ) } return filteredInvitations } getLatestHERequestToRevision() { const { fragment: { recommendations = [] } } = this return recommendations .filter( rec => rec.recommendationType === 'editorRecommendation' && (rec.recommendation === 'minor' || rec.recommendation === 'major'), ) .sort((a, b) => b.createdOn - a.createdOn)[0] } async getReviewers({ UserModel, type }) { const isAccepted = type !== 'pending' const invitations = await this.getInvitations({ isAccepted, type }) return (await Promise.all( invitations.map(inv => UserModel.find(inv.userId)), )) .filter(rev => rev.isActive) .filter(rev => get(rev, 'notifications.email.user')) } } module.exports = Fragment