def test_get_proceedings_object_waiting_for_approval_slow_test_from_fixture(self):

        call_command('loaddata', 'river/fixtures/slow-case.json', verbosity=0)

        user1 = UserObjectFactory(groups=[Group.objects.get(pk=3)])

        objects1 = []
        for i in range(66703, 66723):
            objects1.append(TestModelSlowCase1.objects.create(pk=i))

        objects2 = []
        for i in range(8, 13):
            objects2.append(TestModelSlowCase2.objects.create(pk=i))

        for o in objects1:
            before = datetime.now()
            ProceedingService.get_available_proceedings(o, [o.status], user1)
            after = datetime.now()
            self.assertLess(after - before, timedelta(seconds=0.5))

        for o in objects2:
            before = datetime.now()
            ProceedingService.get_available_proceedings(o, [o.status], user1)
            after = datetime.now()
            self.assertLess(after - before, timedelta(seconds=0.5))
示例#2
0
def post_permissions_change(sender, instance, *args, **kwargs):
    from river.models.proceeding import PENDING
    from river.services.proceeding import ProceedingService

    for proceeding_pending in instance.proceedings.filter(status=PENDING):
        ProceedingService.override_permissions(proceeding_pending,
                                               instance.permissions.all())
示例#3
0
    def test_get_proceedings_object_waiting_for_approval_without_skip(self):
        self.initialize_normal_scenario()

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

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[0],
            self.field, [self.objects[0].my_field],
            user=self.user1)
        self.assertEqual(1, proceedings.count())

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[0],
            self.field, [self.objects[0].my_field],
            user=self.user2)
        self.assertEqual(0, proceedings.count())

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[0],
            self.field, [self.objects[0].my_field],
            user=self.user3)
        self.assertEqual(0, proceedings.count())

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[0],
            self.field, [self.objects[0].my_field],
            user=self.user4)
        self.assertEqual(0, proceedings.count())
示例#4
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()
            if workflow_object.proceeding:
                proceeding.previous = workflow_object.proceeding
            proceeding.save()


            return proceeding

        proceeding = 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.cycle_proceedings(workflow_object, field)
            # ProceedingService.get_next_proceedings(workflow_object, field).update(status=PENDING)

        with ProceedingSignal(workflow_object, field, proceeding), 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_proceedings_object_waiting_for_approval_slow_test(self):
     self.initialize_normal_scenario()
     self.objects = TestModelObjectFactory.create_batch(100)
     for o in self.objects:
         ObjectService.register_object(o)
     before = datetime.now()
     for o in self.objects:
         ProceedingService.get_available_proceedings(o, [o.my_field], user=self.user1)
     after = datetime.now()
     self.assertLess(after - before, timedelta(seconds=2))
示例#6
0
    def proceed(workflow_object, user, next_state=None, god_mod=False):

        def process(workflow_object, user, action, next_state=None, god_mod=False):
            proceedings = ProceedingService.get_available_proceedings(
                workflow_object, [workflow_object.get_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, user)
                        raise RiverException(ErrorCode.INVALID_NEXT_STATE_FOR_USER, "Invalid state is given(%s). Valid states is(are) %s" % (
                            next_state.__str__(), ','.join([ast.__str__() 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 = timezone.now()
            if workflow_object.proceeding:
                proceeding.previous = workflow_object.proceeding
            proceeding.save()

            return proceeding

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

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

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

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

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

        LOGGER.debug("Workflow object %s is proceeded for next transition. Transition: %s -> %s" % (
            workflow_object, workflow_object.get_state().label, workflow_object.get_state()))
    def test_get_proceedings_object_waiting_for_approval_without_skip(self):
        ObjectService.register_object(self.objects[0], self.field)
        ObjectService.register_object(self.objects[1], self.field)

        proceedings = ProceedingService.get_available_proceedings(self.objects[0], self.field, [self.objects[0].my_field], user=self.user1)
        self.assertEqual(1, proceedings.count())

        proceedings = ProceedingService.get_available_proceedings(self.objects[0], self.field, [self.objects[0].my_field], user=self.user2)
        self.assertEqual(0, proceedings.count())

        proceedings = ProceedingService.get_available_proceedings(self.objects[0], self.field, [self.objects[0].my_field], user=self.user3)
        self.assertEqual(0, proceedings.count())

        proceedings = ProceedingService.get_available_proceedings(self.objects[0], self.field, [self.objects[0].my_field], user=self.user4)
        self.assertEqual(0, proceedings.count())
示例#8
0
        def process(workflow_object, user, action, next_state=None, god_mod=False):
            proceedings = ProceedingService.get_available_proceedings(
                workflow_object, [workflow_object.get_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, user)
                        raise RiverException(ErrorCode.INVALID_NEXT_STATE_FOR_USER, "Invalid state is given(%s). Valid states is(are) %s" % (
                            next_state.__str__(), ','.join([ast.__str__() 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 = timezone.now()
            if workflow_object.proceeding:
                proceeding.previous = workflow_object.proceeding
            proceeding.save()

            return proceeding
示例#9
0
        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()
            if workflow_object.proceeding:
                proceeding.previous = workflow_object.proceeding
            proceeding.save()


            return proceeding
示例#10
0
 def get_objects_waiting_for_approval(content_type, user):
     object_pks = []
     WorkflowObjectClass = content_type.model_class()
     for workflow_object in WorkflowObjectClass.objects.all():
         proceedings = ProceedingService.get_available_proceedings(workflow_object, [workflow_object.get_state()], user=user)
         if proceedings.count():
             object_pks.append(workflow_object.pk)
     return WorkflowObjectClass.objects.filter(pk__in=object_pks)
    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())
    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())
示例#13
0
    def register_object(workflow_object, field):
        proceedings = Proceeding.objects.filter(workflow_object=workflow_object, field=field)
        if proceedings.count() == 0:
            ProceedingService.init_proceedings(workflow_object, field)

        return {'state': getattr(workflow_object, field).details()}
示例#14
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)
示例#15
0
        def get_available_proceedings(self, *args, **kwargs):
            from river.services.proceeding import ProceedingService

            return ProceedingService.get_available_proceedings(self, name, [getattr(self, name)], *args, **kwargs)
示例#16
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))
示例#17
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)
    def test_get_proceedings_object_waiting_for_approval_with_skip(self):
        self.initialize_normal_scenario()

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

        proceedings = self.objects[1].get_available_proceedings(self.user1)
        self.assertEqual(1, proceedings.count())
        self.assertEqual(State.objects.get(label='s2'), proceedings[0].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(label='s2')
        ).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(self.objects[1], self.field,
                                                                  [self.objects[1].my_field], user=self.user2)
        self.assertEqual(1, proceedings.count())
        self.assertEqual(State.objects.get(label='s3'), proceedings[0].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(label='s3')
        ).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(self.objects[1], self.field,
                                                                  [self.objects[1].my_field], user=self.user4)
        self.assertEqual(2, proceedings.count())
        self.assertEqual(State.objects.get(label='s4'), proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5'), proceedings[1].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(label='s4')
        ).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(self.objects[1], self.field,
                                                                  [self.objects[1].my_field], user=self.user4)
        self.assertEqual(3, proceedings.count())
        self.assertEqual(State.objects.get(label='s5'), proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s4.1'), proceedings[1].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s4.2'), proceedings[2].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(label='s4')
        ).update(skip=False)
        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(label='s5')
        ).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(self.objects[1], self.field,
                                                                  [self.objects[1].my_field], user=self.user4)
        self.assertEqual(3, proceedings.count())
        self.assertEqual(State.objects.get(label='s4'), proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.1'), proceedings[1].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.2'), proceedings[2].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state__in=State.objects.filter(label__in=['s4', 's5'])
        ).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(self.objects[1], self.field,
                                                                  [self.objects[1].my_field], user=self.user4)
        self.assertEqual(4, proceedings.count())
        self.assertEqual(State.objects.get(label='s4.1'), proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s4.2'), proceedings[1].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.1'), proceedings[2].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.2'), proceedings[3].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state__in=State.objects.filter(label__in=['s4.1', 's5.1'])
        ).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(self.objects[1], self.field,
                                                                  [self.objects[1].my_field], user=self.user4)
        self.assertEqual(2, proceedings.count())
        self.assertEqual(State.objects.get(label='s4.2'), proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.2'), proceedings[1].meta.transition.destination_state)
示例#19
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))
示例#20
0
        def get_available_proceedings(self, *args, **kwargs):
            from river.services.proceeding import ProceedingService

            return ProceedingService.get_available_proceedings(self, [self.get_state()], *args, **kwargs)
    def test_cycle_proceedings(self):
        self.initialize_circular_scenario()

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

        # No Cycle
        self.assertFalse(ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user1, next_state=self.in_progress_state, god_mod=True)
        self.assertEqual(5, Proceeding.objects.filter(object_id=self.objects[0].pk).count())

        # No Cycle
        self.assertFalse(ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user2, next_state=self.resolved_state, god_mod=True)
        self.assertEqual(5, Proceeding.objects.filter(object_id=self.objects[0].pk).count())

        # State is re-opened and cycle is detected. Transition in-progress to resolved proceeding is cloned
        self.assertFalse(ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user3, next_state=self.re_opened_state, god_mod=True)
        self.assertEqual(6, Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(ProceedingMeta.objects.get(transition__source_state=self.in_progress_state,
                                                    transition__destination_state=self.resolved_state),
                         Proceeding.objects.filter(object_id=self.objects[0].pk).latest('date_created').meta)

        # There will be no cycling even if the method is invoked. Because cycling is done in proceeding.
        self.assertFalse(ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.assertEqual(6, Proceeding.objects.filter(object_id=self.objects[0].pk).count())

        # State is in-progress and cycle is detected. Transition resolved to re-opened proceeding is cloned
        self.objects[0].proceed(user=self.user3, next_state=self.in_progress_state, god_mod=True)
        self.assertEqual(7, Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(ProceedingMeta.objects.get(transition__source_state=self.resolved_state,
                                                    transition__destination_state=self.re_opened_state),
                         Proceeding.objects.filter(object_id=self.objects[0].pk).latest('date_created').meta)

        # State is resolved and cycle is detected. Transition re-opened to in-progress proceeding is cloned
        self.objects[0].proceed(user=self.user3, next_state=self.resolved_state, god_mod=True)
        self.assertEqual(8, Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(ProceedingMeta.objects.get(transition__source_state=self.re_opened_state,
                                                    transition__destination_state=self.in_progress_state),
                         Proceeding.objects.filter(object_id=self.objects[0].pk).latest('date_created').meta)

        # State is re-opened and cycle is detected. Transition  in-progress to resolved proceeding is cloned
        self.assertFalse(ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user3, next_state=self.re_opened_state, god_mod=True)
        self.assertEqual(9, Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(ProceedingMeta.objects.get(transition__source_state=self.in_progress_state,
                                                    transition__destination_state=self.resolved_state),
                         Proceeding.objects.filter(object_id=self.objects[0].pk).latest('date_created').meta)

        # State is in-progress and cycle is detected. Transition resolved to re-opened proceeding is cloned
        self.objects[0].proceed(user=self.user3, next_state=self.in_progress_state, god_mod=True)
        self.assertEqual(10, Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(ProceedingMeta.objects.get(transition__source_state=self.resolved_state,
                                                    transition__destination_state=self.re_opened_state),
                         Proceeding.objects.filter(object_id=self.objects[0].pk).latest('date_created').meta)

        # State is resolved and cycle is detected. Transition re-opened to in-progress proceeding is cloned
        self.objects[0].proceed(user=self.user3, next_state=self.resolved_state, god_mod=True)
        self.assertEqual(11, Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(ProceedingMeta.objects.get(transition__source_state=self.re_opened_state,
                                                    transition__destination_state=self.in_progress_state),
                         Proceeding.objects.filter(object_id=self.objects[0].pk).latest('date_created').meta)

        # No Cycle for closed state.
        self.objects[0].proceed(user=self.user4, next_state=self.closed_state, god_mod=True)
        self.assertEqual(11, Proceeding.objects.filter(object_id=self.objects[0].pk).count())
示例#22
0
    def test_cycle_proceedings(self):
        self.initialize_circular_scenario()

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

        # No Cycle
        self.assertFalse(
            ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user1,
                                next_state=self.in_progress_state,
                                god_mod=True)
        self.assertEqual(
            5,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())

        # No Cycle
        self.assertFalse(
            ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user2,
                                next_state=self.resolved_state,
                                god_mod=True)
        self.assertEqual(
            5,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())

        # State is re-opened and cycle is detected. Transition in-progress to resolved proceeding is cloned
        self.assertFalse(
            ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user3,
                                next_state=self.re_opened_state,
                                god_mod=True)
        self.assertEqual(
            6,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(
            ProceedingMeta.objects.get(
                transition__source_state=self.in_progress_state,
                transition__destination_state=self.resolved_state),
            Proceeding.objects.filter(
                object_id=self.objects[0].pk).latest('date_created').meta)

        # There will be no cycling even if the method is invoked. Because cycling is done in proceeding.
        self.assertFalse(
            ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.assertEqual(
            6,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())

        # State is in-progress and cycle is detected. Transition resolved to re-opened proceeding is cloned
        self.objects[0].proceed(user=self.user3,
                                next_state=self.in_progress_state,
                                god_mod=True)
        self.assertEqual(
            7,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(
            ProceedingMeta.objects.get(
                transition__source_state=self.resolved_state,
                transition__destination_state=self.re_opened_state),
            Proceeding.objects.filter(
                object_id=self.objects[0].pk).latest('date_created').meta)

        # State is resolved and cycle is detected. Transition re-opened to in-progress proceeding is cloned
        self.objects[0].proceed(user=self.user3,
                                next_state=self.resolved_state,
                                god_mod=True)
        self.assertEqual(
            8,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(
            ProceedingMeta.objects.get(
                transition__source_state=self.re_opened_state,
                transition__destination_state=self.in_progress_state),
            Proceeding.objects.filter(
                object_id=self.objects[0].pk).latest('date_created').meta)

        # State is re-opened and cycle is detected. Transition  in-progress to resolved proceeding is cloned
        self.assertFalse(
            ProceedingService.cycle_proceedings(self.objects[0], self.field))
        self.objects[0].proceed(user=self.user3,
                                next_state=self.re_opened_state,
                                god_mod=True)
        self.assertEqual(
            9,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(
            ProceedingMeta.objects.get(
                transition__source_state=self.in_progress_state,
                transition__destination_state=self.resolved_state),
            Proceeding.objects.filter(
                object_id=self.objects[0].pk).latest('date_created').meta)

        # State is in-progress and cycle is detected. Transition resolved to re-opened proceeding is cloned
        self.objects[0].proceed(user=self.user3,
                                next_state=self.in_progress_state,
                                god_mod=True)
        self.assertEqual(
            10,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(
            ProceedingMeta.objects.get(
                transition__source_state=self.resolved_state,
                transition__destination_state=self.re_opened_state),
            Proceeding.objects.filter(
                object_id=self.objects[0].pk).latest('date_created').meta)

        # State is resolved and cycle is detected. Transition re-opened to in-progress proceeding is cloned
        self.objects[0].proceed(user=self.user3,
                                next_state=self.resolved_state,
                                god_mod=True)
        self.assertEqual(
            11,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())
        self.assertEqual(
            ProceedingMeta.objects.get(
                transition__source_state=self.re_opened_state,
                transition__destination_state=self.in_progress_state),
            Proceeding.objects.filter(
                object_id=self.objects[0].pk).latest('date_created').meta)

        # No Cycle for closed state.
        self.objects[0].proceed(user=self.user4,
                                next_state=self.closed_state,
                                god_mod=True)
        self.assertEqual(
            11,
            Proceeding.objects.filter(object_id=self.objects[0].pk).count())
示例#23
0
    def test_get_proceedings_object_waiting_for_approval_with_skip(self):
        self.initialize_normal_scenario()

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

        proceedings = self.objects[1].get_available_proceedings(self.user1)
        self.assertEqual(1, proceedings.count())
        self.assertEqual(State.objects.get(label='s2'),
                         proceedings[0].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(
                label='s2')).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[1],
            self.field, [self.objects[1].my_field],
            user=self.user2)
        self.assertEqual(1, proceedings.count())
        self.assertEqual(State.objects.get(label='s3'),
                         proceedings[0].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(
                label='s3')).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[1],
            self.field, [self.objects[1].my_field],
            user=self.user4)
        self.assertEqual(2, proceedings.count())
        self.assertEqual(State.objects.get(label='s4'),
                         proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5'),
                         proceedings[1].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(
                label='s4')).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[1],
            self.field, [self.objects[1].my_field],
            user=self.user4)
        self.assertEqual(3, proceedings.count())
        self.assertEqual(State.objects.get(label='s5'),
                         proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s4.1'),
                         proceedings[1].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s4.2'),
                         proceedings[2].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(
                label='s4')).update(skip=False)
        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state=State.objects.get(
                label='s5')).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[1],
            self.field, [self.objects[1].my_field],
            user=self.user4)
        self.assertEqual(3, proceedings.count())
        self.assertEqual(State.objects.get(label='s4'),
                         proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.1'),
                         proceedings[1].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.2'),
                         proceedings[2].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state__in=State.objects.filter(
                label__in=['s4', 's5'])).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[1],
            self.field, [self.objects[1].my_field],
            user=self.user4)
        self.assertEqual(4, proceedings.count())
        self.assertEqual(State.objects.get(label='s4.1'),
                         proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s4.2'),
                         proceedings[1].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.1'),
                         proceedings[2].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.2'),
                         proceedings[3].meta.transition.destination_state)

        Proceeding.objects.filter(
            field=self.field,
            workflow_object=self.objects[1],
            meta__transition__destination_state__in=State.objects.filter(
                label__in=['s4.1', 's5.1'])).update(skip=True)

        proceedings = ProceedingService.get_available_proceedings(
            self.objects[1],
            self.field, [self.objects[1].my_field],
            user=self.user4)
        self.assertEqual(2, proceedings.count())
        self.assertEqual(State.objects.get(label='s4.2'),
                         proceedings[0].meta.transition.destination_state)
        self.assertEqual(State.objects.get(label='s5.2'),
                         proceedings[1].meta.transition.destination_state)
示例#24
0
        def get_available_proceedings(self, *args, **kwargs):
            from river.services.proceeding import ProceedingService

            return ProceedingService.get_available_proceedings(
                self, name, [getattr(self, name)], *args, **kwargs)
示例#25
0
 def register_object(workflow_object):
     proceedings = Proceeding.objects.filter(workflow_object=workflow_object)
     if proceedings.count() == 0:
         ProceedingService.init_proceedings(workflow_object)
示例#26
0
def post_permissions_change(sender, instance, *args, **kwargs):
    from river.models.proceeding import PENDING
    from river.services.proceeding import ProceedingService

    for proceeding_pending in instance.proceedings.filter(status=PENDING):
        ProceedingService.override_permissions(proceeding_pending, instance.permissions.all())
示例#27
0
        def get_available_proceedings(self, *args, **kwargs):
            from river.services.proceeding import ProceedingService

            return ProceedingService.get_available_proceedings(
                self, [self.get_state()], *args, **kwargs)