Skip to content

Commit

Permalink
2 Feature/kill kownsl activities (#1178)
Browse files Browse the repository at this point in the history
* ✨ Kill all zaak related stuff when resultaat is set

* ✨ Only show review requests in werkvoorraad that arent locked

* ✅ Pass test user task view
  • Loading branch information
damm89 authored Feb 22, 2024
1 parent 35e9b74 commit bd72954
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 26 deletions.
3 changes: 3 additions & 0 deletions backend/src/zac/activities/tests/factories.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import factory

from ..constants import ActivityStatuses


class ActivityFactory(factory.django.DjangoModelFactory):
zaak = factory.Faker("url")
name = factory.Faker("bs")
status = ActivityStatuses.on_going

class Meta:
model = "activities.Activity"
Expand Down
91 changes: 75 additions & 16 deletions backend/src/zac/camunda/tests/test_user_task_view.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import uuid
from copy import deepcopy
from pathlib import Path
from unittest.mock import patch

Expand All @@ -23,9 +24,12 @@
from zgw_consumers.test import generate_oas_component, mock_service_oas_get

from zac.accounts.tests.factories import BlueprintPermissionFactory, UserFactory
from zac.activities.constants import ActivityStatuses
from zac.activities.tests.factories import ActivityFactory
from zac.api.context import ZaakContext
from zac.camunda.data import Task
from zac.contrib.dowc.data import OpenDowc
from zac.contrib.objects.checklists.tests.utils import CHECKLIST_OBJECT
from zac.contrib.objects.kownsl.constants import KownslTypes
from zac.contrib.objects.kownsl.tests.utils import ReviewRequestFactory, ReviewsFactory
from zac.contrib.objects.services import factory_review_request, factory_reviews
Expand Down Expand Up @@ -1144,7 +1148,31 @@ def test_put_zet_resultaat_user_task(self, m, *mocks):
f"{CAMUNDA_URL}task/{TASK_DATA['id']}/assignee",
status_code=201,
)
with patch(

rr = factory_review_request(
ReviewRequestFactory(
user_deadlines={
"user:some-author": "2022-04-14",
}
)
)

activity = ActivityFactory.create(zaak=self.zaak.url)
checklist_object = deepcopy(CHECKLIST_OBJECT)
checklist_object["record"]["data"]["answers"][0] = {
"answer": "",
"question": "Ja?",
"userAssignee": "some-user",
}
patch_get_zaak_context = patch(
"zac.core.camunda.zet_resultaat.serializers.get_zaak_context",
return_value=self.zaak_context,
)
patch_get_resultaattypen = patch(
"zac.core.camunda.zet_resultaat.serializers.get_resultaattypen",
return_value=[factory(ResultaatType, self.resultaattype)],
)
patch_check_document_status = patch(
"zac.core.camunda.zet_resultaat.serializers.check_document_status",
return_value=factory(
OpenDowc,
Expand All @@ -1156,19 +1184,50 @@ def test_put_zet_resultaat_user_task(self, m, *mocks):
}
],
),
):
with patch(
"zac.core.camunda.zet_resultaat.serializers.patch_and_destroy_doc",
return_value={"some-key": "some-value"},
) as patch_and_destroy_doc:
with patch(
"zac.core.camunda.zet_resultaat.serializers.get_zaak_context",
return_value=self.zaak_context,
):
with patch(
"zac.core.camunda.zet_resultaat.serializers.get_resultaattypen",
return_value=[factory(ResultaatType, self.resultaattype)],
):
response = self.client.put(self.task_endpoint, payload)
)
patch_patch_and_destroy_doc = patch(
"zac.core.camunda.zet_resultaat.serializers.patch_and_destroy_doc",
return_value={"some-key": "some-value"},
)
patch_get_all_review_requests_for_zaak = patch(
"zac.core.camunda.zet_resultaat.serializers.get_all_review_requests_for_zaak",
return_value=[rr],
)
patch_lock_review_request = patch(
"zac.core.camunda.zet_resultaat.serializers.lock_review_request",
)
patch_fetch_checklist_object = patch(
"zac.core.camunda.zet_resultaat.serializers.fetch_checklist_object",
return_value=checklist_object,
)
patch_update_object_record_data = patch(
"zac.core.camunda.zet_resultaat.serializers.update_object_record_data",
return_value=checklist_object,
)

with patch_get_zaak_context as pgzc:
with patch_get_resultaattypen as pgrt:
with patch_check_document_status as pcds:
with patch_patch_and_destroy_doc as ppdd:
with patch_get_all_review_requests_for_zaak as pgrrfz:
with patch_lock_review_request as plrr:
with patch_fetch_checklist_object as pfco:
with patch_update_object_record_data as puor:
response = self.client.put(
self.task_endpoint, payload
)
self.assertEqual(response.status_code, 204)
patch_and_destroy_doc.assert_called_once_with(str(_uuid), force=True)

activity.refresh_from_db()
self.assertEqual(activity.status, ActivityStatuses.finished)
self.assertEqual(activity.user_assignee, None)
self.assertEqual(activity.group_assignee, None)

pgzc.assert_called()
pgrt.assert_called()
pcds.assert_called_once()
ppdd.assert_called_once()
pgrrfz.assert_called_once()
plrr.assert_called_once()
pfco.assert_called_once()
puor.assert_called_once()
5 changes: 4 additions & 1 deletion backend/src/zac/contrib/objects/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ def get_review_requests_paginated(
query_params: Optional[Dict] = None,
zaak: Optional[Zaak] = None,
requester: Optional[User] = None,
not_locked: Optional[bool] = False,
page_size: int = 100,
) -> Tuple[List[Dict], Dict]:

Expand All @@ -530,6 +531,8 @@ def get_review_requests_paginated(
data_attrs += [f"zaak__exact__{zaak.url}"]
if requester:
data_attrs += [f"requester__username__exact__{requester.username}"]
if not_locked:
data_attrs += [f"locked__icontains__false"]

response, query_params = _search_meta_objects(
"review_request_objecttype",
Expand All @@ -547,7 +550,7 @@ def get_review_requests_paginated(

def count_review_requests_by_user(requester: User) -> Optional[int]:
response, query_params = get_review_requests_paginated(
requester=requester, page_size=1
requester=requester, page_size=1, not_locked=True
)
return response.get("count", None)

Expand Down
2 changes: 1 addition & 1 deletion backend/src/zac/core/camunda/zet_resultaat/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def get_context(task: Task) -> ZetResultaatContext:
}
open_review_requests = []
for rr in review_requests:
rr.reviews = reviews_given.get(str(rr.id))
rr.reviews = reviews_given.get(str(rr.id), [])
rr.fetched_reviews = True
if rr.get_completed() < rr.num_assigned_users:
open_review_requests.append(rr)
Expand Down
89 changes: 82 additions & 7 deletions backend/src/zac/core/camunda/zet_resultaat/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
from django.conf import settings
from django.utils.translation import gettext_lazy as _

from djangorestframework_camel_case.settings import api_settings
from djangorestframework_camel_case.util import camelize
from rest_framework import serializers
from zgw_consumers.api_models.catalogi import ResultaatType
from zgw_consumers.api_models.documenten import Document
from zgw_consumers.concurrent import parallel
from zgw_consumers.drf.serializers import APIModelSerializer

from zac.activities.api.serializers import ReadActivitySerializer
from zac.activities.constants import ActivityStatuses
from zac.activities.models import Activity
from zac.api.context import get_zaak_context
from zac.camunda.api.serializers import TaskSerializer
Expand All @@ -22,9 +25,15 @@
from zac.contrib.objects.checklists.data import ChecklistQuestion
from zac.contrib.objects.kownsl.api.serializers import ZaakRevReqSummarySerializer
from zac.contrib.objects.kownsl.data import ReviewRequest
from zac.contrib.objects.services import (
fetch_checklist_object,
get_all_review_requests_for_zaak,
get_reviews_for_zaak,
lock_review_request,
)
from zac.core.api.serializers import ResultaatTypeSerializer
from zac.core.cache import invalidate_zaak_cache
from zac.core.services import get_resultaattypen
from zac.core.services import get_resultaattypen, update_object_record_data


@dataclass
Expand Down Expand Up @@ -145,12 +154,7 @@ def get_process_variables(self) -> Dict:
"""
return {"resultaat": self.validated_data["resultaat"]}

def on_task_submission(self) -> None:
"""
Asserts serializer is validated.
"""
assert hasattr(self, "validated_data"), "Serializer is not validated."

def _close_documents(self):
zaakcontext = self._get_zaak_context()
open_documents = check_document_status(zaak=zaakcontext.zaak.url)

Expand All @@ -164,5 +168,76 @@ def _patch_and_destroy_doc(uuid: str):
)
)

def _lock_review_requests(self):
zaakcontext = self._get_zaak_context()
review_requests = get_all_review_requests_for_zaak(zaakcontext.zaak)

def _lock_review_requests(uuid: str):
return lock_review_request(
uuid, f"Zaak is {self.validated_data['resultaat']}."
)

with parallel(max_workers=settings.MAX_WORKERS) as executor:
list(
executor.map(
_lock_review_requests, [str(rr.id) for rr in review_requests]
)
)

def _close_activities(self):
zaakcontext = self._get_zaak_context()
activities = Activity.objects.prefetch_related("events").filter(
zaak=zaakcontext.zaak.url, status=ActivityStatuses.on_going
)
for activity in activities:
activity.user_assignee = None
activity.group_assignee = None
activity.status = ActivityStatuses.finished
activity.save()

def _lock_checklist(self):
zaakcontext = self._get_zaak_context()
checklist = fetch_checklist_object(zaakcontext.zaak)
if checklist:
updated = False
for answer in checklist["record"]["data"]["answers"]:
if not answer["answer"] and (
answer.get("userAssignee") or answer.get("groupAssignee")
):
updated = True
answer["userAssignee"] = ""
answer["groupAssignee"] = ""
checklist["record"]["data"]["lockedBy"] = (
f"{self.context['request'].user}" or "service-account"
)

if updated:
update_object_record_data(
object=checklist,
data=camelize(
checklist["record"]["data"], **api_settings.JSON_UNDERSCOREIZE
),
user=self.context["request"].user,
)

def on_task_submission(self) -> None:
"""
Asserts serializer is validated.
Closes all "open" documents in DoWC.
Locks all review requests.
Ends all activities.
Unassigns all unanswered checklist questions.
Process instance is gracefully ended.
"""
assert hasattr(self, "validated_data"), "Serializer is not validated."
zaakcontext = self._get_zaak_context()

self._close_documents()
self._lock_review_requests()
self._close_activities()
self._lock_checklist()

# Clear all related cache.
invalidate_zaak_cache(zaakcontext.zaak)
3 changes: 2 additions & 1 deletion backend/src/zac/werkvoorraad/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def get_assigned_checklist_answers(self) -> List[Dict]:


@extend_schema(
summary=_("List review requests initiated by user."),
summary=_("List review requests initiated by user that are not locked."),
parameters=[
OpenApiParameter(
name=ProxyPagination().page_size_query_param,
Expand Down Expand Up @@ -326,6 +326,7 @@ def get(self, request, *args, **kwargs):
results, _query_params = get_review_requests_paginated(
query_params=self.get_query_params(),
requester=request.user,
not_locked=True,
)
review_requests = self.resolve_zaken(results["results"])
review_requests = self.resolve_reviews(results["results"])
Expand Down

0 comments on commit bd72954

Please sign in to comment.