def send_message(self, request): logger.info("Sending message based on Camunda message end event") serializer = CamundaMessagerSerializer(data=request.data) if serializer.is_valid(): message_name = serializer.validated_data["message_name"] case_identification = serializer.validated_data["case_id"] process_variables = serializer.validated_data["process_variables"] process_variables["endpoint"] = { "value": settings.ZAKEN_CONTAINER_HOST } raw_response = CamundaService().send_message( message_name=message_name, message_process_variables=process_variables) if raw_response.ok: response = raw_response.json()[0] camunda_id = response["processInstance"]["id"] case = Case.objects.get(identification=case_identification) case.camunda_id = camunda_id case.save() logger.info(f"Message send {message_name} ended succesfully") return Response(status=status.HTTP_200_OK) rendered_content = raw_response.content.decode("UTF-8") logger.error(f"FAIL: Message send response:{rendered_content}") return Response(status=status.HTTP_400_BAD_REQUEST) else: logger.error(f"FAIL: Message send {serializer.errors}") return Response(status=status.HTTP_400_BAD_REQUEST)
def update_decision_with_summon(sender, instance, created, **kwargs): """ TODO: Temporary hook to update decision with a summon instance. This will be resolved when we support multiple summons. """ if created: # TODO: create belastingdienst number if instance.case.summons.count() == 1: instance.summon = instance.case.summons.all()[0] instance.save() task = False for camunda_id in instance.case.camunda_ids: task = CamundaService().get_task_by_task_name_id_and_camunda_id( "task_create_decision", camunda_id) if task: break if task: CamundaService().complete_task( task["id"], {"type_besluit": { "value": instance.decision_type.camunda_option }}, )
def create_summon_instance_in_camunda(sender, instance, created, **kwargs): if created: # TODO: create belastingdienst number if instance.case.summons.count() == 1: instance.summon = instance.case.summons.all()[0] instance.save() task = False for camunda_id in instance.case.camunda_ids: task = CamundaService().get_task_by_task_name_id_and_camunda_id( "task_create_summon", camunda_id ) if task: break if task: CamundaService().complete_task( task["id"], { "type_aanschrijving": {"value": instance.type.camunda_option}, "names": { "value": ", ".join( [person.__str__() for person in instance.persons.all()] ) }, }, )
def complete_camunda_task_create_debrief(sender, instance, created, **kwargs): task = CamundaService().get_task_by_task_name_id_and_camunda_id( "task_create_debrief", instance.case.camunda_id) if task: CamundaService().complete_task( task["id"], {"violation": { "value": instance.violation }})
def complete_camunda_task_create_schedule(sender, instance, created, **kwargs): task = False for camunda_id in instance.case.camunda_ids: task = CamundaService().get_task_by_task_name_id_and_camunda_id( "task_create_schedule", camunda_id ) if task: break if task: CamundaService().complete_task(task["id"])
def complete_camunda_task_create_visit(sender, instance, created, **kwargs): task = CamundaService().get_task_by_task_name_id_and_camunda_id( "task_create_visit", instance.case.camunda_id ) if task: CamundaService().complete_task( task["id"], { "situation": {"value": instance.situation}, "can_next_visit_go_ahead": {"value": instance.can_next_visit_go_ahead}, }, )
def start_camunda_instance(self, identification, request_body): (camunda_id, response) = CamundaService().start_instance( case_identification=identification, request_body=request_body) if camunda_id: case = Case.objects.get(identification=identification) case.camunda_id = camunda_id case.save()
def complete_task(self, request): context = {"request": self.request} serializer = CamundaTaskCompleteSerializer(data=request.data, context=context) if serializer.is_valid(): data = serializer.validated_data # Task data can't be retrieved after it's been completed, so make sure to retrieve it first. task_id = data["camunda_task_id"] task = CamundaService().get_task(task_id) # Boolean values should be converted to string values #ThanksCamunda variables = data.get("variables", {}) for key in variables.keys(): if "value" in variables[key]: if variables[key]["value"] is True: variables[key]["value"] = "true" elif variables[key]["value"] is False: variables[key]["value"] = "false" task_completed = CamundaService().complete_task( data["camunda_task_id"], variables) if task_completed: GenericCompletedTask.objects.create( author=data["author"], case=data["case"], description=task["name"], variables=variables, ) return Response( f"Task {data['camunda_task_id']} has been completed") else: return Response( "Camunda service is offline", status=status.HTTP_503_SERVICE_UNAVAILABLE, ) return Response(status=status.HTTP_400_BAD_REQUEST)
def complete_task(self, request): context = {"request": self.request} serializer = CamundaTaskCompleteSerializer(data=request.data, context=context) if serializer.is_valid(): data = serializer.validated_data # Task data can't be retrieved after it's been completed, so make sure to retrieve it first. task_id = data["camunda_task_id"] task = CamundaService().get_task(task_id) variables = data.get("variables", {}) # Get original structured task form from cache original_camunda_task_form = CamundaService._get_task_form_cache( CamundaService._get_task_form_cache_key(task_id)) form_dict = dict( (t.get("name"), t) for t in original_camunda_task_form) for key, value in variables.items(): # Only for selects, include original readable value from options value["value_verbose"] = (dict( (o.get("value"), o.get("label")) for o in form_dict.get(key).get("options", [])).get( value["value"]) if form_dict.get(key).get( "options", []) else value["value"]) # Include original label value["label"] = form_dict.get(key, {}).get("label") data["variables"] = variables data["description"] = task["name"] GenericCompletedTask.objects.create(**data) return Response( f"Task {data['camunda_task_id']} has been completed") return Response(status=status.HTTP_400_BAD_REQUEST)
def update_due_date(self, request): serializer = CamundaDateUpdateSerializer(data=request.data) if serializer.is_valid(): data = serializer.validated_data response = CamundaService().update_due_date_task( data["camunda_task_id"], data["date"]) if response: return Response(status=status.HTTP_200_OK) return Response( "Camunda service is offline", status=status.HTTP_503_SERVICE_UNAVAILABLE, ) return Response(status=status.HTTP_400_BAD_REQUEST)
def start_process(self, request, pk): serializer = self.serializer_class(data=request.data) if serializer.is_valid(): data = serializer.validated_data instance = data["camunda_process_id"] response = CamundaService().send_message( message_name=instance.camunda_message_name) if response: return Response( data=f"Process has started {str(response.content)}", status=status.HTTP_200_OK, ) return Response( data="Camunda process has not started.", status=status.HTTP_500_INTERNAL_SERVER_ERROR, )
def send_message_inside_of_process(self, request): logger.info( "Sending message based on Camunda message to process instance") serializer = CamundaMessageForProcessInstanceSerializer( data=request.data) if serializer.is_valid(): raw_response = CamundaService().send_message_to_process_instance( message_name=serializer.validated_data["message_name"], process_instance_id=serializer. validated_data["camunda_process_id"], ) if raw_response.ok: return Response(status=status.HTTP_200_OK) else: return Response(status=status.HTTP_503_SERVICE_UNAVAILABLE, ) else: logger.error(f"FAIL: Message send {serializer.errors}") return Response(status=status.HTTP_400_BAD_REQUEST, data=serializer.errors)
def list(self, request): role = request.GET.get(role_parameter.name) tasks = CamundaService().get_tasks_by_role(role) # Camunda tasks can be an empty list or boolean. TODO: This should just be one datatype if tasks is False: return Response( "Camunda service is offline", status=status.HTTP_503_SERVICE_UNAVAILABLE, ) else: result = [] for task in tasks: try: case = Case.objects.filter( case_states__case_process_id=task["processInstanceId"] ).first() if case: task["case"] = case result.append(task) except Case.DoesNotExist: print( f'Dropping task {task["processInstanceId"]} as the case cannot be found.' )
class CaseViewSet( CaseEventsMixin, mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet, ): permission_classes = [IsInAuthorizedRealm | TopKeyAuth] serializer_class = CaseSerializer queryset = Case.objects.all() def get_serializer_class(self, *args, **kwargs): if self.action in ["create", "update"]: return CaseCreateUpdateSerializer return self.serializer_class @extend_schema( parameters=[ date_parameter, start_date_parameter, open_cases_parameter, team_parameter, reason_parameter, open_status_parameter, no_pagination_parameter, ], description="Case filter query parameters", responses={200: CaseSerializer(many=True)}, ) def list(self, request): date = request.GET.get(date_parameter.name, None) start_date = request.GET.get(start_date_parameter.name, None) open_cases = request.GET.get(open_cases_parameter.name, None) team = request.GET.get(team_parameter.name, None) reason = request.GET.get(reason_parameter.name, None) open_status = request.GET.get(open_status_parameter.name, None) no_pagination = request.GET.get(no_pagination_parameter.name, None) queryset = self.get_queryset() if date: queryset = queryset.filter(start_date=date) if start_date: queryset = queryset.filter(start_date__gte=start_date) if open_cases: open_cases = open_cases == "true" queryset = queryset.filter(end_date__isnull=open_cases) if team: queryset = queryset.filter(team=team) if reason: queryset = queryset.filter(reason=reason) if open_status: queryset = queryset.filter( case_states__end_date__isnull=True, case_states__status__name=open_status, ) if no_pagination == "true": serializer = CaseSerializer(queryset, many=True) return Response(serializer.data) paginator = PageNumberPagination() context = paginator.paginate_queryset(queryset, request) serializer = CaseSerializer(context, many=True) return paginator.get_paginated_response(serializer.data) @extend_schema( parameters=[ postal_code_parameter, street_number_parameter, street_name_parameter, suffix_parameter, team_parameter, ], description="Search query parameters", responses={200: CaseSerializer(many=True)}, operation=None, ) @action(detail=False, methods=["get"], url_path="search") def search(self, request): postal_code = request.GET.get(postal_code_parameter.name, None) street_name = request.GET.get(street_name_parameter.name, None) number = request.GET.get(street_number_parameter.name, None) suffix = request.GET.get(suffix_parameter.name, None) team = request.GET.get(team_parameter.name, None) if postal_code is None and street_name is None: return HttpResponseBadRequest( "A postal_code or street_name queryparameter should be provided" ) if postal_code is not None and number is None: return HttpResponseBadRequest("number queryparameter is required") if street_name is not None and number is None: return HttpResponseBadRequest("number queryparameter is required") address_queryset = search( street_name=street_name, postal_code=postal_code, number=number, suffix=suffix, ) cases = Case.objects.none() for address in address_queryset: cases = cases | address.cases.all() cases = cases.filter(end_date=None) if team: cases = cases.filter(team=team) paginator = PageNumberPagination() context = paginator.paginate_queryset(cases, request) serializer = CaseSerializer(context, many=True) return paginator.get_paginated_response(serializer.data) @action(detail=False, methods=["post"], url_path="generate-mock") def mock_cases(self, request): try: assert (settings.DEBUG or settings.ENVIRONMENT == "acceptance"), "Incorrect enviroment" mock() except Exception as e: return Response(data={"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_200_OK) @extend_schema( description="Get Camunda tasks for this Case", responses={status.HTTP_200_OK: CamundaTaskSerializer(many=True)}, ) @action(detail=True, methods=["get"], url_path="tasks") def get_tasks(self, request, pk): case = self.get_object() camunda_tasks = [] for camunda_id in case.camunda_ids: camunda_tasks.extend( CamundaService().get_all_tasks_by_instance_id(camunda_id)) # Camunda tasks can be an empty list or boolean. TODO: This should just be one datatype if camunda_tasks is False: return Response( "Camunda service is offline", status=status.HTTP_503_SERVICE_UNAVAILABLE, ) serializer = CamundaTaskSerializer(camunda_tasks, many=True) return Response(serializer.data)
def create_summon_instance_in_camunda(sender, instance, created, **kwargs): # CamundaService().send_message( # "model_create_summon", # json.dumps( # { # "names": { # "value": ", ".join( # [person.__str__() for person in instance.persons.all()] # ) # }, # "type_aanschrijving": { # "value": instance.type.camunda_option, # }, # "sluitingsbesluit": { # "value": instance.intention_closing_decision, # }, # } # ), # ) if created and "test" not in sys.argv: (camunda_id, _) = CamundaService().start_instance( case_identification=instance.case.identification, process="zaak_wonen_summon", request_body=json.dumps( { "variables": { "names": { "value": ", ".join( [person.__str__() for person in instance.persons.all()] ), "type": "String", }, "type_aanschrijving": { "value": instance.type.camunda_option, "type": "String", }, "sluitingsbesluit": { "value": False, "type": "Boolean", }, "case_identification": { "value": instance.case.identification, "type": "String", }, "zaken_access_token": { "value": settings.CAMUNDA_SECRET_KEY, "type": "String", }, "zaken_state_endpoint": { "value": f'{settings.ZAKEN_CONTAINER_HOST}{reverse("camunda-workers-state")}', "type": "String", }, "zaken_end_state_endpoint": { "value": f'{settings.ZAKEN_CONTAINER_HOST}{reverse("camunda-workers-end-state")}', "type": "String", }, "endpoint": { "value": settings.ZAKEN_CONTAINER_HOST, "type": "String", }, } } ), ) case = instance.case case.camunda_id = camunda_id case.save()
def get_schedule_task(case): task = CamundaService().get_task_by_task_name_id_and_camunda_id( "task_create_schedule", case.camunda_id ) return task
class CamundaWorkerViewSet(viewsets.ViewSet): """ This is a view which can be be request from the Camunda workflow. """ permission_classes = [IsInAuthorizedRealm | CamundaKeyAuth] serializer_class = CamundaStateWorkerSerializer @extend_schema( description="A Camunda service task for setting state", responses={200: None}, ) @action( detail=False, url_path="state", methods=["post"], serializer_class=CamundaStateWorkerSerializer, ) def state(self, request): logger.info("Starting Camunda service task for setting state") logger.info(request.body) serializer = CamundaStateWorkerSerializer(data=request.data) if serializer.is_valid(): state = serializer.save() logger.info("State set succesfully") return Response(data=state.id, status=status.HTTP_201_CREATED) else: logger.error(f"State could not be set: {serializer.errors}") logger.info(serializer.errors) return Response(status=status.HTTP_400_BAD_REQUEST) @extend_schema( description="A Camunda service task for ending a state", responses={200: None}, ) @action( detail=False, url_path="end-state", methods=["post"], serializer_class=CamundaEndStateWorkerSerializer, ) def end_state(self, request): logger.info("Starting Camunda service task for ending state") serializer = CamundaEndStateWorkerSerializer(data=request.data) if serializer.is_valid(): state = serializer.validated_data["state_identification"] state.end_state() state.save() logger.info("State ended succesfully") return Response(status=status.HTTP_200_OK) else: logger.error(f"State could not be ended: {serializer.errors}") return Response(status=status.HTTP_400_BAD_REQUEST) @extend_schema( description= "A Camunda service task for starting process based on message", responses={200: None}, ) @action( detail=False, url_path="send-message-start-process", methods=["post"], serializer_class=CamundaMessagerSerializer, ) def send_message(self, request): logger.info("Sending message based on Camunda message end event") serializer = CamundaMessagerSerializer(data=request.data) if serializer.is_valid(): message_name = serializer.validated_data["message_name"] case_identification = serializer.validated_data[ "case_identification"] if serializer.validated_data["process_variables"]: process_variables = serializer.validated_data[ "process_variables"] else: process_variables = {} try: case = Case.objects.get(id=case_identification) except Case.DoesNotExist: return Response( data="Camunda process has not started. Case does not exist", status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) case_process_instance = CaseProcessInstance.objects.create( case=case) case_process_id = case_process_instance.process_id.__str__() raw_response = CamundaService().send_message( message_name=message_name, case_identification=case_identification, case_process_id=case_process_id, message_process_variables=process_variables, ) if raw_response.ok: response = raw_response.json()[0] camunda_id = response["processInstance"]["id"] case = Case.objects.get(id=case_identification) case.add_camunda_id(camunda_id) case_process_instance.camunda_process_id = camunda_id case.save() case_process_instance.save() logger.info(f"Message send {message_name} ended succesfully") return Response(status=status.HTTP_200_OK) rendered_content = raw_response.content.decode("UTF-8") logger.error(f"FAIL: Message send response:{rendered_content}") return Response(status=status.HTTP_400_BAD_REQUEST)
def create_generic_completed_instance_in_camunda(sender, instance, created, **kwargs): if created: CamundaService().complete_task(instance.camunda_task_id, instance.variables)
serializer = self.serializer_class(data=request.data) if serializer.is_valid(): data = serializer.validated_data instance = data["camunda_process_id"] try: case = Case.objects.get(id=pk) except Case.DoesNotExist: return Response( data="Camunda process has not started. Case does not exist", status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) response = CamundaService().send_message( message_name=instance.camunda_message_name, case_identification=case.id) try: json_response = response.json()[0] camunda_process_id = json_response["processInstance"]["id"] except Exception: return Response( data= f"Camunda process has not started. Json response not valid {str(response.content)}", status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) case.add_camunda_id(camunda_process_id) case.save()