forked from Amsterdam/signals
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ZGW app that can replicate a Signal to an external case managemen…
…t system
- Loading branch information
Showing
12 changed files
with
219 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2018 - 2021 Gemeente Amsterdam | ||
# Copyright (C) 2022 Delta10 B.V. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. | ||
from django.contrib import admin | ||
|
||
from .models import Case | ||
|
||
|
||
@admin.register(Case) | ||
class EmailTemplate(admin.ModelAdmin): | ||
list_display = [ | ||
'_signal', | ||
'external_id' | ||
] | ||
|
||
readonly_fields = [ | ||
'_signal', | ||
'external_id' | ||
] | ||
|
||
def has_add_permission(self, request, obj=None): | ||
return False | ||
|
||
def has_delete_permission(self, request, obj=None): | ||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. | ||
from django.apps import AppConfig | ||
|
||
|
||
class ZgwConfig(AppConfig): | ||
name = 'signals.apps.zgw' | ||
verbose_name = 'Replication to case management system' | ||
default_auto_field = 'django.db.models.BigAutoField' | ||
|
||
def ready(self): | ||
from . import signal_receivers # noqa |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. | ||
# Generated by Django 3.2.15 on 2022-10-24 21:35 | ||
import django.db.models.deletion | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('signals', '0162_signal_user_HISTORY'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Case', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('external_id', models.CharField(db_index=True, max_length=100)), | ||
('_signal', models.OneToOneField( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name='zgw_case', | ||
to='signals.signal' | ||
)), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. | ||
from django.db import models | ||
|
||
from signals.apps.signals.models import Signal | ||
|
||
|
||
class Case(models.Model): | ||
"""Relate a Signal to a case in an external system""" | ||
_signal = models.OneToOneField( | ||
Signal, | ||
related_name='zgw_case', | ||
on_delete=models.CASCADE, | ||
) | ||
|
||
external_id = models.CharField(max_length=100, db_index=True) | ||
|
||
def __str__(self): | ||
return str(self._signal.id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. | ||
from django.conf import settings | ||
from django.dispatch import receiver | ||
|
||
from signals.apps.signals.managers import create_initial, update_status | ||
|
||
from . import tasks | ||
|
||
|
||
@receiver(create_initial, dispatch_uid='zgw_create_initial') | ||
def create_initial_handler(sender, signal_obj, *args, **kwargs): | ||
if settings.ZGW_API_URL: | ||
tasks.create_initial.delay(signal_id=signal_obj.pk) | ||
|
||
|
||
@receiver(update_status, dispatch_uid='zgw_update_status') | ||
def update_status_handler(sender, signal_obj, status, *args, **kwargs): | ||
if settings.ZGW_API_URL: | ||
tasks.update_status.delay(status_id=status.pk) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# SPDX-License-Identifier: MPL-2.0 | ||
# Copyright (C) 2022 Delta10 B.V. | ||
from urllib.parse import urljoin | ||
|
||
import requests | ||
from django.conf import settings | ||
from django.template.loader import render_to_string | ||
from django.utils.timezone import localtime | ||
|
||
from signals.apps.signals.models import Signal, Status | ||
from signals.apps.signals.workflow import AFGEHANDELD, GEANNULEERD, GEMELD, HEROPEND | ||
from signals.celery import app | ||
|
||
from .models import Case | ||
|
||
MAX_RETRIES = 10 | ||
DEFAULT_RETRY_DELAY = 60*10 | ||
|
||
AUTORETRY_FOR = ( | ||
requests.exceptions.Timeout, | ||
requests.exceptions.ConnectionError, | ||
requests.exceptions.HTTPError | ||
) | ||
|
||
|
||
@app.task(autoretry_for=AUTORETRY_FOR, max_retries=MAX_RETRIES, default_retry_delay=DEFAULT_RETRY_DELAY) | ||
def create_initial(signal_id): | ||
signal = Signal.objects.get(pk=signal_id) | ||
|
||
context = { | ||
'signal': signal, | ||
'url': urljoin(settings.FRONTEND_URL, f'/manage/incident/{signal.id}'), | ||
} | ||
|
||
einddatumGepland = signal.created_at.strftime('%Y-%m-%d') | ||
if signal.category_assignment: | ||
einddatumGepland = localtime(signal.category_assignment.deadline).strftime('%Y-%m-%d') | ||
|
||
data = { | ||
'bronorganisatie': settings.ZGW_BRONORGANISATIE, | ||
'omschrijving': render_to_string('case_description.txt', context=context), | ||
'toelichting': render_to_string('case_explanation.html', context=context), | ||
'zaaktype': settings.ZGW_ZAAKTYPE, | ||
'registratiedatum': localtime(signal.created_at).strftime('%Y-%m-%d'), | ||
'tijdstipRegistratie': localtime(signal.created_at).strftime('%Y-%m-%d %H:%M'), | ||
'verantwoordelijkeOrganisatie': settings.ZGW_VERANTWOORDELIJKE_ORGANISATIE, | ||
'startdatum': localtime(signal.created_at).strftime('%Y-%m-%d'), | ||
'einddatumGepland': einddatumGepland, | ||
'kenmerken': [ | ||
{ | ||
'kenmerk': signal.get_id_display(), | ||
'bron': 'SIGNALEN' | ||
} | ||
] | ||
} | ||
|
||
url = urljoin(settings.ZGW_API_URL, '/zgw/zaken') | ||
response = requests.post(url, json=data, timeout=int(settings.ZGW_TIMEOUT)) | ||
response.raise_for_status() | ||
|
||
case = response.json() | ||
|
||
Case.objects.update_or_create(external_id=case['uuid'], defaults={ | ||
'_signal': signal | ||
}) | ||
|
||
# Trigger async job to set current status of Signal | ||
app.send_task('signals.apps.zgw.tasks.update_status', args=[signal.status.pk]) | ||
|
||
|
||
@app.task(autoretry_for=AUTORETRY_FOR, max_retries=MAX_RETRIES, default_retry_delay=DEFAULT_RETRY_DELAY) | ||
def update_status(status_id): | ||
status = Status.objects.get(pk=status_id) | ||
signal = status._signal | ||
|
||
if not hasattr(signal, 'zgw_case'): | ||
return # this Signal is not registered in an external case management system | ||
|
||
zgw_states = { | ||
GEMELD: settings.ZGW_STATUS_RECEIVED, | ||
HEROPEND: settings.ZGW_STATUS_RECEIVED, | ||
AFGEHANDELD: settings.ZGW_STATUS_DONE, | ||
GEANNULEERD: settings.ZGW_STATUS_DONE | ||
} | ||
|
||
if not zgw_states.get(status.state): | ||
return # this state change is not registered in the case management system | ||
|
||
data = { | ||
'zaak': signal.zgw_case.external_id, | ||
'statustype': zgw_states[status.state], | ||
'datumStatusGezet': localtime(status.created_at).strftime('%Y-%m-%d') | ||
} | ||
|
||
url = urljoin(settings.ZGW_API_URL, '/zgw/statussen') | ||
response = requests.post(url, json=data, timeout=int(settings.ZGW_TIMEOUT)) | ||
response.raise_for_status() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{{ signal.category_assignment.category.name }} - {{ signal.get_id_display }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Bekijk voor meer informatie <a href="{{ url }}" target="_blank">{{ url }}</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters