Skip to content
Snippets Groups Projects
Collection.js 3.81 KiB
Newer Older
const { flatten, isEmpty, maxBy, get } = require('lodash')

class Collection {
  constructor({ collection = {} }) {
    this.collection = collection
  }

  async updateStatusByRecommendation({
    recommendation,
    isHandlingEditor = false,
  }) {
    let newStatus
    if (isHandlingEditor) {
      newStatus = 'pendingApproval'
      if (['minor', 'major'].includes(recommendation)) {
        newStatus = 'revisionRequested'
      }
    } else {
      if (recommendation === 'minor') {
        newStatus = 'reviewCompleted'
      }
        newStatus = 'underReview'
  }

  async updateFinalStatusByRecommendation({ recommendation }) {
    let newStatus
    switch (recommendation) {
      case 'reject':
        newStatus = 'rejected'
        break
      case 'publish':
        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') {
        this.updateStatus({ newStatus: 'reviewCompleted' })
      } else {
        this.updateFinalStatusByRecommendation({
          recommendation,
        })
      }
    } else {
      this.updateStatusByRecommendation({
        recommendation,
        isHandlingEditor: true,
      })
    }
  }
    const [firstName, lastName] = this.collection.handlingEditor.name.split(' ')
    return lastName || firstName

  async getAllCollectionFragments({ FragmentModel }) {
    const allCollectionFragments = await Promise.all(
      get(this.collection, 'fragments', []).map(async fragmentId => {
        const fragment = await FragmentModel.find(fragmentId)
        return fragment
      }),
    )
    return allCollectionFragments
  }

  async getReviewerNumber({ userId, FragmentModel }) {
    const allCollectionFragments = await this.getAllCollectionFragments({
      FragmentModel,
    })
    const allCollectionInvitations = flatten(
      allCollectionFragments.map(fragment => fragment.invitations),
    )
    const allNumberedInvitationsForUser = allCollectionInvitations
    if (isEmpty(allNumberedInvitationsForUser)) {
      const maxReviewerNumber = get(
        maxBy(allCollectionInvitations, 'reviewerNumber'),
        'reviewerNumber',
        0,
      )
      return maxReviewerNumber + 1
    }
    return allNumberedInvitationsForUser[0].reviewerNumber
  }