From 490b79e07d6974ac511abc1b3fec6260b176a91e Mon Sep 17 00:00:00 2001 From: Paul Schilling Date: Tue, 31 Oct 2023 12:57:07 +0100 Subject: [PATCH] [#1829] Make call-to-action url + text configurable per statustype --- .../cms/cases/tests/test_contactform.py | 38 +++++++++++++++- src/open_inwoner/cms/cases/views/status.py | 32 ++++++++++++-- src/open_inwoner/openzaak/admin.py | 3 ++ src/open_inwoner/openzaak/catalog.py | 20 --------- .../0028_zaaktype_statustype_button.py | 43 +++++++++++++++++++ src/open_inwoner/openzaak/models.py | 20 +++++++++ src/open_inwoner/openzaak/tests/factories.py | 1 + .../openzaak/tests/test_case_detail.py | 12 ++++++ src/open_inwoner/openzaak/tests/test_cases.py | 2 + .../templates/pages/cases/status_inner.html | 8 +++- 10 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 src/open_inwoner/openzaak/migrations/0028_zaaktype_statustype_button.py diff --git a/src/open_inwoner/cms/cases/tests/test_contactform.py b/src/open_inwoner/cms/cases/tests/test_contactform.py index 7a0425375d..c9e6d4e139 100644 --- a/src/open_inwoner/cms/cases/tests/test_contactform.py +++ b/src/open_inwoner/cms/cases/tests/test_contactform.py @@ -113,6 +113,18 @@ def setUp(self): vertrouwelijkheidaanduiding=VertrouwelijkheidsAanduidingen.openbaar, indicatieInternOfExtern="extern", ) + # + # statuses + # + self.status_new = generate_oas_component( + "zrc", + "schemas/Status", + url=f"{ZAKEN_ROOT}statussen/3da81560-c7fc-476a-ad13-beu760sle929", + zaak=self.zaak["url"], + statustype=f"{CATALOGI_ROOT}statustypen/e3798107-ab27-4c3c-977d-777yu878km09", + datumStatusGezet="2021-01-12", + statustoelichting="", + ) self.status_finish = generate_oas_component( "zrc", "schemas/Status", @@ -122,6 +134,21 @@ def setUp(self): datumStatusGezet="2021-03-12", statustoelichting="", ) + # + # status types + # + self.status_type_new = generate_oas_component( + "ztc", + "schemas/StatusType", + url=self.status_new["statustype"], + zaaktype=self.zaaktype["url"], + catalogus=f"{CATALOGI_ROOT}catalogussen/1b643db-81bb-d71bd5a2317a", + omschrijving="Initial request", + omschrijvingGeneriek="Nieuw", + statustekst="", + volgnummer=1, + isEindstatus=False, + ) self.status_type_finish = generate_oas_component( "ztc", "schemas/StatusType", @@ -129,7 +156,10 @@ def setUp(self): zaaktype=self.zaaktype["url"], catalogus=f"{CATALOGI_ROOT}catalogussen/1b643db-81bb-d71bd5a2317a", omschrijving="Finish", - omschrijvingGeneriek="some content", + omschrijvingGeneriek="Afgehandeld", + statustekst="", + volgnummer=1, + isEindstatus=True, ) self.result = generate_oas_component( "zrc", @@ -181,6 +211,12 @@ def _setUpMocks(self, m): ]: self.matchers.append(m.get(resource["url"], json=resource)) + # mock `fetch_status_types_no_cache` + m.get( + f"{CATALOGI_ROOT}statustypen?zaaktype={self.zaak['zaaktype']}", + json=paginated_response([self.status_type_new, self.status_type_finish]), + ) + self.matchers += [ m.get( f"{ZAKEN_ROOT}rollen?zaak={self.zaak['url']}", diff --git a/src/open_inwoner/cms/cases/views/status.py b/src/open_inwoner/cms/cases/views/status.py index 888d0a1bc5..8c6553499a 100644 --- a/src/open_inwoner/cms/cases/views/status.py +++ b/src/open_inwoner/cms/cases/views/status.py @@ -172,6 +172,16 @@ def get_context_data(self, **kwargs): "status_indicator_text", None, ), + "call_to_action_url": getattr( + statustype_config_mapping.get(end_statustype.url), + "call_to_action_url", + None, + ), + "call_to_action_text": getattr( + statustype_config_mapping.get(end_statustype.url), + "call_to_action_text", + None, + ), } context["case"] = { @@ -204,6 +214,7 @@ def get_context_data(self, **kwargs): ) else: context["case"] = None + return context def get_upload_info_context(self, case: Zaak): @@ -258,21 +269,23 @@ def get_upload_info_context(self, case: Zaak): ), } - def get_result_display(self, case: Zaak) -> str: + @staticmethod + def get_result_display(case: Zaak) -> str: if case.resultaat: result = fetch_single_result(case.resultaat) if result: return result.toelichting return None - def get_initiator_display(self, case: Zaak) -> str: + @staticmethod + def get_initiator_display(case: Zaak) -> str: roles = fetch_case_roles(case.url, RolOmschrijving.initiator) if not roles: return "" return ", ".join([get_role_name_display(r) for r in roles]) + @staticmethod def get_statuses_data( - self, statuses: List[Status], lookup: TranslationLookup, statustype_config_mapping: Optional[dict] = None, @@ -293,11 +306,22 @@ def get_statuses_data( "status_indicator_text", None, ), + "call_to_action_url": getattr( + statustype_config_mapping.get(s.statustype.url), + "call_to_action_url", + None, + ), + "call_to_action_text": getattr( + statustype_config_mapping.get(s.statustype.url), + "call_to_action_text", + None, + ), } for s in statuses ] - def get_case_document_files(self, case: Zaak) -> List[SimpleFile]: + @staticmethod + def get_case_document_files(case: Zaak) -> List[SimpleFile]: case_info_objects = fetch_case_information_objects(case.url) # get the information objects for the case objects diff --git a/src/open_inwoner/openzaak/admin.py b/src/open_inwoner/openzaak/admin.py index bab3b3cad3..7dfb67daa6 100644 --- a/src/open_inwoner/openzaak/admin.py +++ b/src/open_inwoner/openzaak/admin.py @@ -182,7 +182,10 @@ class ZaakTypeStatusTypeConfigInline(admin.TabularInline): "zaaktype_uuids", "status_indicator", "status_indicator_text", + "show_document_uploads", "document_upload_description", + "call_to_action_url", + "call_to_action_text", ] readonly_fields = [ "statustekst", diff --git a/src/open_inwoner/openzaak/catalog.py b/src/open_inwoner/openzaak/catalog.py index c0a13b23ed..de40998b06 100644 --- a/src/open_inwoner/openzaak/catalog.py +++ b/src/open_inwoner/openzaak/catalog.py @@ -83,26 +83,6 @@ def fetch_single_status_type(status_type_url: str) -> Optional[StatusType]: return status_type -@cache_result( - "resultaat_type:{resultaat_type_url}", timeout=settings.CACHE_ZGW_CATALOGI_TIMEOUT -) -def fetch_single_resultaat_type(resultaat_type_url: str) -> Optional[ResultaatType]: - client = build_client("catalogi") - - if client is None: - return - - try: - response = client.retrieve("resultaattype", url=resultaat_type_url) - except (RequestException, ClientError) as e: - logger.exception("exception while making request", exc_info=e) - return - - resultaat_type = factory(ResultaatType, response) - - return resultaat_type - - # not cached because only used by tools, # and because caching (stale) listings can break lookups def fetch_zaaktypes_no_cache() -> List[ZaakType]: diff --git a/src/open_inwoner/openzaak/migrations/0028_zaaktype_statustype_button.py b/src/open_inwoner/openzaak/migrations/0028_zaaktype_statustype_button.py new file mode 100644 index 0000000000..7b737fb68d --- /dev/null +++ b/src/open_inwoner/openzaak/migrations/0028_zaaktype_statustype_button.py @@ -0,0 +1,43 @@ +# Generated by Django 3.2.20 on 2023-10-31 11:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("openzaak", "0027_zaaktype_resultaattype_config"), + ] + + operations = [ + migrations.AddField( + model_name="zaaktypestatustypeconfig", + name="call_to_action_text", + field=models.CharField( + blank=True, + default="", + help_text="The text displayed on the call-to-action button", + max_length=48, + verbose_name="Call to action text", + ), + ), + migrations.AddField( + model_name="zaaktypestatustypeconfig", + name="call_to_action_url", + field=models.URLField( + blank=True, + default="", + help_text="The url the user will be sent to by clicking on the call-to-action button", + verbose_name="Call to action url", + ), + ), + migrations.AddField( + model_name="zaaktypestatustypeconfig", + name="show_document_uploads", + field=models.BooleanField( + default=True, + help_text="Wheter document uploads are to be shown", + verbose_name="Show document uploads", + ), + ), + ] diff --git a/src/open_inwoner/openzaak/models.py b/src/open_inwoner/openzaak/models.py index 909a524dab..3d8fc6d043 100644 --- a/src/open_inwoner/openzaak/models.py +++ b/src/open_inwoner/openzaak/models.py @@ -362,6 +362,26 @@ class ZaakTypeStatusTypeConfig(models.Model): "Description that will be shown above the document upload widget in a case detail page" ), ) + show_document_uploads = models.BooleanField( + default=True, + verbose_name=_("Show document uploads"), + help_text=_("Wheter document uploads are to be shown"), + ) + call_to_action_url = models.URLField( + blank=True, + default="", + verbose_name=_("Call to action url"), + help_text=_( + "The url the user will be sent to by clicking on the call-to-action button" + ), + ) + call_to_action_text = models.CharField( + max_length=48, + blank=True, + default="", + verbose_name=_("Call to action text"), + help_text=_("The text displayed on the call-to-action button"), + ) class Meta: verbose_name = _("Zaaktype Statustype Configuration") diff --git a/src/open_inwoner/openzaak/tests/factories.py b/src/open_inwoner/openzaak/tests/factories.py index 1195cf2292..fd4c85d185 100644 --- a/src/open_inwoner/openzaak/tests/factories.py +++ b/src/open_inwoner/openzaak/tests/factories.py @@ -115,6 +115,7 @@ class ZaakTypeStatusTypeConfigFactory(factory.django.DjangoModelFactory): zaaktype_config = factory.SubFactory(ZaakTypeConfigFactory) statustype_url = factory.Faker("url") omschrijving = factory.Faker("pystr", max_chars=80) + # call_to_action_url = statustype_url class Meta: model = ZaakTypeStatusTypeConfig diff --git a/src/open_inwoner/openzaak/tests/test_case_detail.py b/src/open_inwoner/openzaak/tests/test_case_detail.py index 3dedeabf24..40ae8cbf2a 100644 --- a/src/open_inwoner/openzaak/tests/test_case_detail.py +++ b/src/open_inwoner/openzaak/tests/test_case_detail.py @@ -378,6 +378,8 @@ def test_status_is_retrieved_when_user_logged_in_via_digid(self, m): statustype_url=self.status_type_finish["url"], status_indicator=StatusIndicators.success, status_indicator_text="bar", + call_to_action_url="https://www.example.com", + call_to_action_text="Click me", ) self._setUpMocks(m) @@ -406,12 +408,16 @@ def test_status_is_retrieved_when_user_logged_in_via_digid(self, m): "label": "Initial request", "status_indicator": "warning", "status_indicator_text": "foo", + "call_to_action_url": "", + "call_to_action_text": "", }, { "date": datetime.datetime(2021, 3, 12), "label": "Finish", "status_indicator": "success", "status_indicator_text": "bar", + "call_to_action_url": "https://www.example.com", + "call_to_action_text": "Click me", }, ], # only one visible information object @@ -440,6 +446,8 @@ def test_pass_endstatus_type_data_if_endstatus_not_reached(self, m): statustype_url=self.status_type_finish["url"], status_indicator=StatusIndicators.success, status_indicator_text="bar", + call_to_action_url="https://www.example.com", + call_to_action_text="Click me", ) self._setUpMocks(m, use_eindstatus=False) @@ -464,6 +472,8 @@ def test_pass_endstatus_type_data_if_endstatus_not_reached(self, m): "label": "Finish", "status_indicator": "success", "status_indicator_text": "bar", + "call_to_action_url": "https://www.example.com", + "call_to_action_text": "Click me", }, "description": "Coffee zaaktype", "statuses": [ @@ -472,6 +482,8 @@ def test_pass_endstatus_type_data_if_endstatus_not_reached(self, m): "label": "Initial request", "status_indicator": "warning", "status_indicator_text": "foo", + "call_to_action_url": "", + "call_to_action_text": "", }, ], # only one visible information object diff --git a/src/open_inwoner/openzaak/tests/test_cases.py b/src/open_inwoner/openzaak/tests/test_cases.py index 7078014e37..a5b5d009ed 100644 --- a/src/open_inwoner/openzaak/tests/test_cases.py +++ b/src/open_inwoner/openzaak/tests/test_cases.py @@ -194,6 +194,8 @@ def setUpTestData(cls): statustype_url=cls.status_type1["url"], status_indicator=StatusIndicators.warning, status_indicator_text="U moet documenten toevoegen", + call_to_action_url="https://example.com", + call_to_action_text="yolo", ) # open cls.zaak1 = generate_oas_component( diff --git a/src/open_inwoner/templates/pages/cases/status_inner.html b/src/open_inwoner/templates/pages/cases/status_inner.html index 07dd5ceee3..3746af3109 100644 --- a/src/open_inwoner/templates/pages/cases/status_inner.html +++ b/src/open_inwoner/templates/pages/cases/status_inner.html @@ -48,8 +48,12 @@