Skip to content

Commit

Permalink
Merge pull request #181 from Amsterdam/feature/display-zds-data
Browse files Browse the repository at this point in the history
Feature/display zds data
  • Loading branch information
tcoenen authored Jan 17, 2019
2 parents 4341d42 + 0edcdfb commit a1da9c1
Show file tree
Hide file tree
Showing 54 changed files with 2,080 additions and 262 deletions.
4 changes: 2 additions & 2 deletions api/app/signals/apps/signals/workflow.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""
Model the workflow of responding to a Signal (melding) as state machine.
"""
# ! There is also a workflow.py file in the ZDS. This file needs to be updated with
# ! the status as wel when this file is updated.
# ! Made sure that the status that is created also exists in the ZTC on staging. Otherwise it will
# ! fail with setting the status.

# Internal statusses
LEEG = ''
Expand Down
Empty file.
51 changes: 51 additions & 0 deletions api/app/signals/apps/zds/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from rest_framework import serializers
from zds_client.client import ClientError

from signals.apps.signals.models import Signal


class SignalZDSSerializer(serializers.ModelSerializer):
"""Read-only serializer for `Signal` object."""
id = serializers.IntegerField(label='ID', read_only=True)
zds_case = serializers.SerializerMethodField()
zds_statusses = serializers.SerializerMethodField()
zds_images = serializers.SerializerMethodField()

def get_zds_case(self, obj):
if hasattr(obj, 'case'):
try:
return obj.case.get_case()
except ClientError:
return {}
return {}

def get_zds_statusses(self, obj):
if hasattr(obj, 'case'):
try:
return obj.case.get_statusses()
except ClientError:
return []
return []

def get_zds_images(self, obj):
if hasattr(obj, 'case'):
try:
return obj.case.get_images()
except ClientError:
return []
return []

class Meta(object):
model = Signal
fields = (
'id',
'zds_case',
'zds_statusses',
'zds_images',
)
read_only_fields = (
'id',
'zds_case',
'zds_statusses',
'zds_images',
)
16 changes: 16 additions & 0 deletions api/app/signals/apps/zds/api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Views that are used exclusively by the V0 API
"""
from datapunt_api.rest import DatapuntViewSet

from signals.apps.signals.models import Signal
from signals.auth.backend import JWTAuthBackend

from .serializers import SignalZDSSerializer


class SignalZDSViewSet(DatapuntViewSet):
authentication_classes = (JWTAuthBackend, )
queryset = Signal.objects.order_by('-created_at')
serializer_detail_class = SignalZDSSerializer
serializer_class = SignalZDSSerializer
12 changes: 8 additions & 4 deletions api/app/signals/apps/zds/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class ZDSClient:
def __init__(self):
Client.load_config(**{
config = {
'zrc': {
'scheme': settings.ZRC_SCHEME,
'host': settings.ZRC_HOST,
Expand All @@ -23,11 +23,15 @@ def __init__(self):
'port': settings.ZTC_PORT,
'auth': settings.ZTC_AUTH,
}
})
}

Client.load_config(**config)

def get_client(self, client_type):
# TODO: This needs to contain the correct base_path for the staging environment Amsterdam.
return Client(client_type, base_path='/{}/api/v1/'.format(client_type))
base_path = settings.ZDS_BASE_PATH
base_path = base_path.format(client_type)

return Client(client_type, base_path=base_path)

@property
def ztc(self):
Expand Down

This file was deleted.

98 changes: 98 additions & 0 deletions api/app/signals/apps/zds/management/commands/sync_zds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import logging
from datetime import timedelta

from django.core.management.base import BaseCommand
from django.utils import timezone

from signals.apps.signals.models import Signal
from signals.apps.zds.exceptions import (
CaseConnectionException,
CaseNotCreatedException,
DocumentConnectionException,
DocumentNotCreatedException,
StatusNotCreatedException
)
from signals.apps.zds.tasks import (
add_document_to_case,
add_status_to_case,
connect_signal_to_case,
create_case,
create_document
)

logger = logging.getLogger(__name__)


class Command(BaseCommand):
help = "Sync the signals with the ZDS components"

def handle(self, *args, **options):
"""
Only select the signals that are 10 minutes old.
Select signals that have no case or have not been done syncing.
"""
ten_minutes_ago = timezone.now() - timedelta(seconds=600)
signals_id1 = list(Signal.objects.filter(case__isnull=True).values_list('pk', flat=True))
signals_id2 = list(Signal.objects.filter(case__isnull=False).filter(
case__sync_completed=False).values_list('pk', flat=True))
signal_ids = signals_id1 + signals_id2

signals = Signal.objects.filter(pk__in=signal_ids, created_at__lte=ten_minutes_ago)
for signal in signals:
self.sync_case(signal)

def sync_case(self, signal):
"""
Push the case to the ZDS components.
If the case already exists, it will continue to connect the signal to the case.
If everything went correctly, continue to add the statusses to the ZDS components.
"""
try:
create_case(signal)

try:
connect_signal_to_case(signal)
self.sync_status(signal)
except CaseConnectionException as case_exception:
logger.exception(case_exception)
self.stderr.write(repr(case_exception))
except CaseNotCreatedException as case_exception:
logger.exception(case_exception)
self.stderr.write(repr(case_exception))

def sync_status(self, signal):
"""
Push all the statusses that are connected to the signal to the ZDS components.
If a status already exists, it will skip the status and continue with the other statusses.
If everything went correctly, continue to add the documents to the ZDS components.
"""
try:
for status in signal.statuses.order_by('created_at'):
add_status_to_case(signal, status)

self.sync_document(signal)
except StatusNotCreatedException as status_exception:
logger.exception(status_exception)
self.stderr.write(repr(status_exception))

def sync_document(self, signal):
"""
Push all the images that are connected to the signal to the ZDS components.
If the document already exists, set signal sync to completed.
"""
if signal.image:
try:
case_document = create_document(signal)

try:
add_document_to_case(signal, case_document)
signal.case.sync_completed = True
signal.case.save()
except DocumentConnectionException as document_exception:
logger.exception(document_exception)
self.stderr.write(repr(document_exception))
except DocumentNotCreatedException as document_exception:
logger.exception(document_exception)
self.stderr.write(repr(document_exception))
33 changes: 27 additions & 6 deletions api/app/signals/apps/zds/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,59 @@

class CaseSignalManager(models.Manager):

def create_case_signal(self, url, signal):
def create_case_signal(self, signal):
"""
Create a connection between a case and a signal.
"""
from .models import CaseSignal

with transaction.atomic():
case_signal = CaseSignal(zrc_link=url, signal=signal)
case_signal = CaseSignal(signal=signal)
case_signal.save()

return case_signal

def add_status(self, url, case_signal):
def add_status(self, case_signal, status):
"""
Adds a status to a case.
"""
from .models import CaseStatus

with transaction.atomic():
case_status = CaseStatus(zrc_link=url, case_signal=case_signal)
case_status = CaseStatus(case_signal=case_signal, status=status)
case_status.save()

return case_status

def add_document(self, url, case_signal):
def add_document(self, case_signal):
"""
Adds a link between the case and the document. Zo that it is also known in the signals app.
"""
from .models import CaseDocument

with transaction.atomic():
case_document = CaseDocument(drc_link=url, case_signal=case_signal)
case_document = CaseDocument(case_signal=case_signal)
case_document.save()

return case_document

def add_zrc_link(self, url, obj):
with transaction.atomic():
obj.zrc_link = url
obj.save()

return obj

def add_drc_link(self, url, obj):
with transaction.atomic():
obj.drc_link = url
obj.save()

return obj

def set_connected_in_external_system(self, obj):
with transaction.atomic():
obj.connected_in_external_system = True
obj.save()

return obj
28 changes: 28 additions & 0 deletions api/app/signals/apps/zds/migrations/0006_auto_20181213_1740.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 2.1.2 on 2018-12-13 16:40

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('signals', '0028_auto_20181204_0915'),
('zds', '0005_auto_20181211_1503'),
]

operations = [
migrations.AddField(
model_name='casesignal',
name='sync_completed',
field=models.BooleanField(blank=True, default=False),
),
migrations.AddField(
model_name='casestatus',
name='status',
field=models.OneToOneField(
null=True, on_delete=django.db.models.deletion.CASCADE,
related_name='case_status', to='signals.Status'
),
),
]
Loading

0 comments on commit a1da9c1

Please sign in to comment.