예제 #1
0
    def proceed(workflow_object, field, user, next_state=None, god_mod=False):

        def process(workflow_object, field, user, action, next_state=None, god_mod=False):
            current_state = getattr(workflow_object, field)
            proceedings = ProceedingService.get_available_proceedings(workflow_object, field, [current_state], user=user, god_mod=god_mod)
            c = proceedings.count()
            if c == 0:
                raise RiverException(ErrorCode.NO_AVAILABLE_NEXT_STATE_FOR_USER, "There is no available state for destination for the user.")
            if c > 1:
                if next_state:
                    proceedings = proceedings.filter(meta__transition__destination_state=next_state)
                    if proceedings.count() == 0:
                        available_states = StateService.get_available_states(workflow_object, field, user)
                        raise RiverException(ErrorCode.INVALID_NEXT_STATE_FOR_USER,
                                             "Invalid state is given(%s). Valid states is(are) %s" % (next_state.__unicode__(), ','.join([ast.__unicode__() for ast in available_states])))
                else:
                    raise RiverException(ErrorCode.NEXT_STATE_IS_REQUIRED, "State must be given when there are multiple states for destination")
            proceeding = proceedings[0]
            proceeding.status = action
            proceeding.transactioner = user
            proceeding.transaction_date = datetime.now()
            proceeding.save()

            c = False
            track = workflow_object.proceeding_track
            while not c:
                track, c = proceeding.tracks.get_or_create(previous_track=track)
            return proceeding, track

        proceeding, track = process(workflow_object, field, user, APPROVED, next_state, god_mod)
        workflow_object.proceeding_track = track

        current_state = getattr(workflow_object, field)
        # Any other proceeding is left?
        required_proceedings = ProceedingService.get_available_proceedings(workflow_object, field, [current_state], destination_state=next_state, god_mod=god_mod)

        transition_status = False
        if required_proceedings.count() == 0:
            setattr(workflow_object, field, proceeding.meta.transition.destination_state)
            transition_status = True

            # Next states should be PENDING back again if there is circle.
            ProceedingService.get_next_proceedings(workflow_object, field).update(status=PENDING)

        with ProceedingSignal(workflow_object, field, proceeding, track), TransitionSignal(transition_status, workflow_object, field, proceeding), FinalSignal(workflow_object, field):
            workflow_object.save()

        LOGGER.debug("Workflow object %s for field %s is proceeded for next transition. Transition: %s -> %s" % (workflow_object, field, current_state.label, getattr(workflow_object, field).label))
    def test_get_next_proceedings(self):
        self.initialize_normal_scenario()

        ObjectService.register_object(self.objects[0], self.field)
        ObjectService.register_object(self.objects[1], self.field)

        proceedings = ProceedingService.get_next_proceedings(self.objects[0], self.field)
        self.assertEqual(9, proceedings.count())

        self.objects[0].proceed(self.user1)

        proceedings = ProceedingService.get_next_proceedings(self.objects[0], self.field)
        self.assertEqual(8, proceedings.count())

        self.objects[0].proceed(self.user2)

        # Two proceedings exist on same level
        proceedings = ProceedingService.get_next_proceedings(self.objects[0], self.field)
        self.assertEqual(7, proceedings.count())

        self.objects[0].proceed(self.user3)

        proceedings = ProceedingService.get_next_proceedings(self.objects[0], self.field)
        self.assertEqual(6, proceedings.count())

        self.objects[0].proceed(self.user4, next_state=State.objects.get(label='s4'))
        proceedings = ProceedingService.get_next_proceedings(self.objects[0], self.field)
        self.assertEqual(2, proceedings.count())

        self.objects[0].proceed(self.user4, next_state=State.objects.get(label='s4.1'))
        proceedings = ProceedingService.get_next_proceedings(self.objects[0], self.field)
        self.assertEqual(0, proceedings.count())
    def test_get_next_proceedings(self):
        self.initialize_normal_scenario()

        ObjectService.register_object(self.objects[0])
        ObjectService.register_object(self.objects[1])

        proceedings = ProceedingService.get_next_proceedings(self.objects[0])
        self.assertEqual(9, proceedings.count())

        self.objects[0].proceed(self.user1)

        proceedings = ProceedingService.get_next_proceedings(self.objects[0])
        self.assertEqual(8, proceedings.count())

        self.objects[0].proceed(self.user2)

        # Two proceedings exist on same level
        proceedings = ProceedingService.get_next_proceedings(self.objects[0])
        self.assertEqual(7, proceedings.count())

        self.objects[0].proceed(self.user3)

        proceedings = ProceedingService.get_next_proceedings(self.objects[0])
        self.assertEqual(6, proceedings.count())

        self.objects[0].proceed(self.user4, next_state=State.objects.get(label='s4'))
        proceedings = ProceedingService.get_next_proceedings(self.objects[0])
        self.assertEqual(2, proceedings.count())

        self.objects[0].proceed(self.user4, next_state=State.objects.get(label='s4.1'))
        proceedings = ProceedingService.get_next_proceedings(self.objects[0])
        self.assertEqual(0, proceedings.count())
예제 #4
0
        def next_proceedings(self):
            from river.services.proceeding import ProceedingService

            return getattr(self,
                           name) in ProceedingService.get_next_proceedings(
                               ContentType.objects.get_for_model(self), name)
예제 #5
0
        def next_proceedings(self):
            from river.services.proceeding import ProceedingService

            return getattr(self, name) in ProceedingService.get_next_proceedings(ContentType.objects.get_for_model(self), name)
예제 #6
0
        def next_proceedings(self):
            from river.services.proceeding import ProceedingService

            return self.get_state() in ProceedingService.get_next_proceedings(ContentType.objects.get_for_model(self))
예제 #7
0
        def next_proceedings(self):
            from river.services.proceeding import ProceedingService

            return self.get_state() in ProceedingService.get_next_proceedings(
                ContentType.objects.get_for_model(self))
예제 #8
0
    def proceed(workflow_object, field, user, next_state=None, god_mod=False):
        def process(workflow_object,
                    field,
                    user,
                    action,
                    next_state=None,
                    god_mod=False):
            current_state = getattr(workflow_object, field)
            proceedings = ProceedingService.get_available_proceedings(
                workflow_object,
                field, [current_state],
                user=user,
                god_mod=god_mod)
            c = proceedings.count()
            if c == 0:
                raise RiverException(
                    ErrorCode.NO_AVAILABLE_NEXT_STATE_FOR_USER,
                    "There is no available state for destination for the user."
                )
            if c > 1:
                if next_state:
                    proceedings = proceedings.filter(
                        meta__transition__destination_state=next_state)
                    if proceedings.count() == 0:
                        available_states = StateService.get_available_states(
                            workflow_object, field, user)
                        raise RiverException(
                            ErrorCode.INVALID_NEXT_STATE_FOR_USER,
                            "Invalid state is given(%s). Valid states is(are) %s"
                            % (next_state.__unicode__(), ','.join([
                                ast.__unicode__() for ast in available_states
                            ])))
                else:
                    raise RiverException(
                        ErrorCode.NEXT_STATE_IS_REQUIRED,
                        "State must be given when there are multiple states for destination"
                    )
            proceeding = proceedings[0]
            proceeding.status = action
            proceeding.transactioner = user
            proceeding.transaction_date = datetime.now()
            proceeding.save()

            c = False
            track = workflow_object.proceeding_track
            while not c:
                track, c = proceeding.tracks.get_or_create(
                    previous_track=track)
            return proceeding, track

        proceeding, track = process(workflow_object, field, user, APPROVED,
                                    next_state, god_mod)

        current_state = getattr(workflow_object, field)
        # Any other proceeding is left?
        required_proceedings = ProceedingService.get_available_proceedings(
            workflow_object,
            field, [current_state],
            destination_state=next_state,
            god_mod=god_mod)

        transition_status = False
        if required_proceedings.count() == 0:
            setattr(workflow_object, field,
                    proceeding.meta.transition.destination_state)
            transition_status = True

            # Next states should be PENDING back again if there is circle.
            ProceedingService.get_next_proceedings(
                workflow_object, field).update(status=PENDING)

        with ProceedingSignal(workflow_object, field,
                              proceeding, track), TransitionSignal(
                                  transition_status, workflow_object, field,
                                  proceeding), FinalSignal(
                                      workflow_object, field):
            workflow_object.save()

        LOGGER.debug(
            "Workflow object %s for field %s is proceeded for next transition. Transition: %s -> %s"
            % (workflow_object, field, current_state.label,
               getattr(workflow_object, field).label))