예제 #1
0
    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()]
                    )
                },
            },
        )
예제 #4
0
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
            }})
예제 #5
0
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"])
예제 #6
0
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},
            },
        )
예제 #7
0
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)
예제 #9
0
    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)
예제 #11
0
    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,
        )
예제 #12
0
    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)
예제 #13
0
    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.'
                    )
예제 #14
0
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)
예제 #15
0
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()
예제 #16
0
 def get_schedule_task(case):
     task = CamundaService().get_task_by_task_name_id_and_camunda_id(
         "task_create_schedule", case.camunda_id
     )
     return task
예제 #17
0
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)
예제 #18
0
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()