def test_get_approvements_object_waiting_for_approval_without_skip(self): ObjectService.register_object(self.objects[0], self.field) ObjectService.register_object(self.objects[1], self.field) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[0], self.field, [self.objects[0].my_field], user=self.user1) self.assertEqual(1, approvements.count()) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[0], self.field, [self.objects[0].my_field], user=self.user2) self.assertEqual(0, approvements.count()) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[0], self.field, [self.objects[0].my_field], user=self.user3) self.assertEqual(0, approvements.count()) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[0], self.field, [self.objects[0].my_field], user=self.user4) self.assertEqual(0, approvements.count())
def process(workflow_object, field, user, action, next_state=None, god_mod=False): current_state = getattr(workflow_object, field) approvements = ApprovementService.get_approvements_object_waiting_for_approval(workflow_object, field, [current_state], user=user, god_mod=god_mod) c = approvements.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: approvements = approvements.filter(meta__transition__destination_state=next_state) if approvements.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") approvement = approvements[0] approvement.status = action approvement.transactioner = user approvement.transaction_date = datetime.now() approvement.save() c = False track = workflow_object.approvement_track while not c: track, c = approvement.tracks.get_or_create(previous_track=track) return approvement, track
def get_objects_waiting_for_approval(content_type, field, user): object_pks = [] WorkflowObjectClass = content_type.model_class() for workflow_object in WorkflowObjectClass.objects.all(): current_state = getattr(workflow_object, field) approvements = ApprovementService.get_approvements_object_waiting_for_approval(workflow_object, field, [current_state], user=user) if approvements.count(): object_pks.append(workflow_object.pk) return WorkflowObjectClass.objects.filter(pk__in=object_pks)
def approve_transition(workflow_object, field, user, next_state=None, god_mod=False): approvement, track = TransitionService.process(workflow_object, field, user, APPROVED, next_state, god_mod) workflow_object.approvement_track = track current_state = getattr(workflow_object, field) # Any other approvement is left? required_approvements = ApprovementService.get_approvements_object_waiting_for_approval(workflow_object, field, [current_state], destination_state=next_state, god_mod=god_mod) transition_status = False if required_approvements.count() == 0: setattr(workflow_object, field, approvement.meta.transition.destination_state) transition_status = True # Next states should be PENDING back again if there is circle. ApprovementService.get_next_approvements(workflow_object, field).update(status=PENDING) with ApprovementSignal(workflow_object, field, approvement, track), TransitionSignal(transition_status, workflow_object, field, approvement), FinalSignal(workflow_object, field): workflow_object.save() LOGGER.debug("Workflow object %s for field %s is approved for next transition. Transition: %s -> %s" % (workflow_object, field, current_state.label, getattr(workflow_object, field).label))
def approve_transition(workflow_object, field, user, next_state=None, god_mod=False): approvement, track = TransitionService.process(workflow_object, field, user, APPROVED, next_state, god_mod) workflow_object.approvement_track = track current_state = getattr(workflow_object, field) # Any other approvement is left? required_approvements = ApprovementService.get_approvements_object_waiting_for_approval( workflow_object, field, [current_state], destination_state=next_state, god_mod=god_mod) transition_status = False if required_approvements.count() == 0: setattr(workflow_object, field, approvement.meta.transition.destination_state) transition_status = True # Next states should be PENDING back again if there is circle. ApprovementService.get_next_approvements( workflow_object, field).update(status=PENDING) with ApprovementSignal(workflow_object, field, approvement, track), TransitionSignal( transition_status, workflow_object, field, approvement), FinalSignal( workflow_object, field): workflow_object.save() LOGGER.debug( "Workflow object %s for field %s is approved for next transition. Transition: %s -> %s" % (workflow_object, field, current_state.label, getattr(workflow_object, field).label))
def test_get_next_approvements(self): ObjectService.register_object(self.objects[0], self.field) ObjectService.register_object(self.objects[1], self.field) approvements = ApprovementService.get_next_approvements(self.objects[0], self.field) self.assertEqual(9, approvements.count()) self.objects[0].approve(self.user1) approvements = ApprovementService.get_next_approvements(self.objects[0], self.field) self.assertEqual(8, approvements.count()) self.objects[0].approve(self.user2) # Two approvements exist on same level approvements = ApprovementService.get_next_approvements(self.objects[0], self.field) self.assertEqual(8, approvements.count()) self.objects[0].approve(self.user3) approvements = ApprovementService.get_next_approvements(self.objects[0], self.field) self.assertEqual(6, approvements.count()) self.objects[0].approve(self.user4, next_state=State.objects.get(label='s4')) approvements = ApprovementService.get_next_approvements(self.objects[0], self.field) self.assertEqual(2, approvements.count()) self.objects[0].approve(self.user4, next_state=State.objects.get(label='s4.1')) approvements = ApprovementService.get_next_approvements(self.objects[0], self.field) self.assertEqual(0, approvements.count())
def process(workflow_object, field, user, action, next_state=None, god_mod=False): current_state = getattr(workflow_object, field) approvements = ApprovementService.get_approvements_object_waiting_for_approval( workflow_object, field, [current_state], user=user, god_mod=god_mod) c = approvements.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: approvements = approvements.filter( meta__transition__destination_state=next_state) if approvements.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" ) approvement = approvements[0] approvement.status = action approvement.transactioner = user approvement.transaction_date = datetime.now() approvement.save() c = False track = workflow_object.approvement_track while not c: track, c = approvement.tracks.get_or_create(previous_track=track) return approvement, track
def next_approvements(self): from river.services.approvement import ApprovementService return getattr(self, name) in ApprovementService.get_next_approvements(ContentType.objects.get_for_model(self), name)
def get_available_approvements(self, *args, **kwargs): from river.services.approvement import ApprovementService return ApprovementService.get_approvements_object_waiting_for_approval(self, name, [getattr(self, name)], *args, **kwargs)
def register_object(workflow_object, field): approvements = Approvement.objects.filter(workflow_object=workflow_object, field=field) if approvements.count() == 0: ApprovementService.init_approvements(workflow_object, field) return {'state': getattr(workflow_object, field).details()}
def post_permissions_change(sender, instance, *args, **kwargs): from river.models.approvement import PENDING from river.services.approvement import ApprovementService for approvement_pending in instance.approvements.filter(status=PENDING): ApprovementService.override_permissions(approvement_pending, instance.permissions.all())
def test_get_approvements_object_waiting_for_approval_with_skip(self): ObjectService.register_object(self.objects[0], self.field) ObjectService.register_object(self.objects[1], self.field) approvements = self.objects[1].get_available_approvements(self.user1) self.assertEqual(1, approvements.count()) self.assertEqual(State.objects.get(label='s2'), approvements[0].meta.transition.destination_state) Approvement.objects.filter( field=self.field, workflow_object=self.objects[1], meta__transition__destination_state=State.objects.get(label='s2') ).update(skip=True) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[1], self.field, [self.objects[1].my_field], user=self.user2) self.assertEqual(1, approvements.count()) self.assertEqual(State.objects.get(label='s3'), approvements[0].meta.transition.destination_state) Approvement.objects.filter( field=self.field, workflow_object=self.objects[1], meta__transition__destination_state=State.objects.get(label='s3') ).update(skip=True) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[1], self.field, [self.objects[1].my_field], user=self.user4) self.assertEqual(2, approvements.count()) self.assertEqual(State.objects.get(label='s4'), approvements[0].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s5'), approvements[1].meta.transition.destination_state) Approvement.objects.filter( field=self.field, workflow_object=self.objects[1], meta__transition__destination_state=State.objects.get(label='s4') ).update(skip=True) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[1], self.field, [self.objects[1].my_field], user=self.user4) self.assertEqual(3, approvements.count()) self.assertEqual(State.objects.get(label='s5'), approvements[0].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s4.1'), approvements[1].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s4.2'), approvements[2].meta.transition.destination_state) Approvement.objects.filter( field=self.field, workflow_object=self.objects[1], meta__transition__destination_state=State.objects.get(label='s4') ).update(skip=False) Approvement.objects.filter( field=self.field, workflow_object=self.objects[1], meta__transition__destination_state=State.objects.get(label='s5') ).update(skip=True) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[1], self.field, [self.objects[1].my_field], user=self.user4) self.assertEqual(3, approvements.count()) self.assertEqual(State.objects.get(label='s4'), approvements[0].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s5.1'), approvements[1].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s5.2'), approvements[2].meta.transition.destination_state) Approvement.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) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[1], self.field, [self.objects[1].my_field], user=self.user4) self.assertEqual(4, approvements.count()) self.assertEqual(State.objects.get(label='s4.1'), approvements[0].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s4.2'), approvements[1].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s5.1'), approvements[2].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s5.2'), approvements[3].meta.transition.destination_state) Approvement.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) approvements = ApprovementService.get_approvements_object_waiting_for_approval(self.objects[1], self.field, [self.objects[1].my_field], user=self.user4) self.assertEqual(2, approvements.count()) self.assertEqual(State.objects.get(label='s4.2'), approvements[0].meta.transition.destination_state) self.assertEqual(State.objects.get(label='s5.2'), approvements[1].meta.transition.destination_state)