예제 #1
0
class ReviewAction(BaseAction):
    target = models.ForeignKey('Preprint',
                               related_name='actions',
                               on_delete=models.CASCADE)

    trigger = models.CharField(max_length=31, choices=ReviewTriggers.choices())
    from_state = models.CharField(max_length=31,
                                  choices=ReviewStates.choices())
    to_state = models.CharField(max_length=31, choices=ReviewStates.choices())
예제 #2
0
class ReviewableMixin(MachineableMixin):
    """Something that may be included in a reviewed collection and is subject to a reviews workflow.
    """
    TriggersClass = ReviewTriggers

    machine_state = models.CharField(max_length=15,
                                     db_index=True,
                                     choices=ReviewStates.choices(),
                                     default=ReviewStates.INITIAL.value)

    class Meta:
        abstract = True

    MachineClass = ReviewsMachine

    @property
    def in_public_reviews_state(self):
        public_states = PUBLIC_STATES.get(self.provider.reviews_workflow)
        if not public_states:
            return False
        return self.machine_state in public_states

    def run_withdraw(self, user, comment):
        """Run the 'withdraw' state transition and create a corresponding Action.

        Params:
            user: The user triggering this transition.
            comment: Text describing why.
        """
        return self._run_transition(self.TriggersClass.WITHDRAW.value,
                                    user=user,
                                    comment=comment)
예제 #3
0
class ReviewActionSerializer(BaseActionSerializer):
    class Meta:
        type_ = 'review-actions'

    filterable_fields = frozenset([
        'id',
        'trigger',
        'from_state',
        'to_state',
        'date_created',
        'date_modified',
        'provider',
        'target',
    ])

    comment = HideIfProviderCommentsPrivate(
        ser.CharField(max_length=65535, required=False))
    trigger = ser.ChoiceField(choices=ReviewTriggers.choices())
    from_state = ser.ChoiceField(choices=ReviewStates.choices(),
                                 read_only=True)
    to_state = ser.ChoiceField(choices=ReviewStates.choices(), read_only=True)

    provider = RelationshipField(
        read_only=True,
        related_view='providers:preprint-providers:preprint-provider-detail',
        related_view_kwargs={'provider_id': '<target.provider._id>'},
        filter_key='target__provider___id',
    )

    creator = HideIfProviderCommentsAnonymous(
        RelationshipField(
            read_only=True,
            related_view='users:user-detail',
            related_view_kwargs={'user_id': '<creator._id>'},
            filter_key='creator__guids___id',
            always_embed=True,
        ))

    target = TargetRelationshipField(
        target_class=PreprintService,
        read_only=False,
        required=True,
        related_view='preprints:preprint-detail',
        related_view_kwargs={'preprint_id': '<target._id>'},
        filter_key='target__guids___id',
    )

    def create(self, validated_data):
        trigger = validated_data.get('trigger')
        if trigger != ReviewTriggers.WITHDRAW.value:
            return super(ReviewActionSerializer, self).create(validated_data)
        user = validated_data.pop('user')
        target = validated_data.pop('target')
        comment = validated_data.pop('comment', '')
        try:
            return target.run_withdraw(user=user, comment=comment)
        except InvalidTriggerError as e:
            # Invalid transition from the current state
            raise Conflict(e.message)
        else:
            raise JSONAPIAttributeException(attribute='trigger',
                                            detail='Invalid trigger.')