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())
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))
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))
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())
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
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
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 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 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 get_available_proceedings(self, *args, **kwargs): from river.services.proceeding import ProceedingService return ProceedingService.get_available_proceedings( self, name, [getattr(self, name)], *args, **kwargs)
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)
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)
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)
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 get_available_proceedings(self, *args, **kwargs): from river.services.proceeding import ProceedingService return ProceedingService.get_available_proceedings( self, [self.get_state()], *args, **kwargs)