From cd0b7b18377f8061e030aac98a81807ea5a5c2fa Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 21 Jan 2022 13:04:19 +0100
Subject: [PATCH] esirius_swi: compute a fancy status (#60958)

---
 passerelle/contrib/esirius_swi/models.py |  4 +-
 passerelle/contrib/esirius_swi/utils.py  | 62 ++++++++++++++++++++++++
 tests/test_esirius_swi.py                | 62 +++++++++++++++++++-----
 3 files changed, 116 insertions(+), 12 deletions(-)
 create mode 100644 passerelle/contrib/esirius_swi/utils.py

diff --git a/passerelle/contrib/esirius_swi/models.py b/passerelle/contrib/esirius_swi/models.py
index 9c496e2a..d102e4b6 100644
--- a/passerelle/contrib/esirius_swi/models.py
+++ b/passerelle/contrib/esirius_swi/models.py
@@ -19,16 +19,18 @@ from urllib.parse import urljoin
 import zeep
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
+from . import utils
+
 
 class ESiriusSwi(BaseResource):
     base_url = models.URLField(_('Base API URL'), help_text=_('with trailing slash'))
     verify_cert = models.BooleanField(default=True, verbose_name=_('Check HTTPS Certificate validity'))
 
     category = _('Business Process Connectors')
 
     class Meta:
@@ -74,10 +76,10 @@ class ESiriusSwi(BaseResource):
                 'realMaxWaitingTime',
                 'resourceNumber',
                 'serviceWaitingIndicatorWSList',
                 'siteCode',
                 'waitingVisitorNumber',
                 'weekHoursWS',
             ]:
                 item_dest[key] = item_src[key]
-            data.append(item_dest)
+            data.append(utils.compute_status(item_dest))
         return {'err': 0, 'data': data}
diff --git a/passerelle/contrib/esirius_swi/utils.py b/passerelle/contrib/esirius_swi/utils.py
new file mode 100644
index 00000000..a7083959
--- /dev/null
+++ b/passerelle/contrib/esirius_swi/utils.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2021 Entr'ouvert
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+def compute_status(raw_data):
+    data = {
+        'name': raw_data['name'],
+        'status': 'closed',
+        'waiting_visitors': raw_data['cumulatedWaitingVisitorNumber'],
+        'focus': {
+            'value': None,
+            'unit': None,
+            'html_color': '#ff1800',
+        },
+        'raw_data': raw_data,
+    }
+
+    # closed
+    if not raw_data['resourceNumber']:
+        return data
+    try:
+        hours, minutes, seconds = (int(x) for x in raw_data['estimatedAvgWaitingTime'].split(':'))
+    except ValueError:
+        return data
+
+    data['status'] = 'open'
+    unit = ''
+    if hours:
+        data['focus']['value'] = hours
+        unit = 'heure'
+    elif minutes:
+        data['focus']['value'] = minutes
+        unit = 'minute'
+    else:
+        data['focus']['value'] = seconds
+        unit = 'seconde'
+    if data['focus']['value'] > 1:
+        unit = unit + 's'
+    data['focus']['unit'] = unit
+    for color in [
+        {'time_limit': '00:05:00', 'html_color': '#c3f000'},
+        {'time_limit': '00:10:00', 'html_color': '#ffff00'},
+        {'time_limit': '00:20:00', 'html_color': '#ffd100'},
+        {'time_limit': '00:40:00', 'html_color': '#ff5e00'},
+    ]:
+        if raw_data['estimatedAvgWaitingTime'] < color['time_limit']:
+            data['focus']['html_color'] = color['html_color']
+            break
+    return data
diff --git a/tests/test_esirius_swi.py b/tests/test_esirius_swi.py
index 90ae2943..f07c4d28 100644
--- a/tests/test_esirius_swi.py
+++ b/tests/test_esirius_swi.py
@@ -16,16 +16,17 @@
 import json
 import os
 
 import mock
 import pytest
 import utils
 
 from passerelle.contrib.esirius_swi.models import ESiriusSwi
+from passerelle.contrib.esirius_swi.utils import compute_status
 
 pytestmark = pytest.mark.django_db
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'esirius_swi')
 
 
 def get_xml_file(filename):
     with open(os.path.join(TEST_BASE_DIR, filename), 'rb') as desc:
@@ -60,35 +61,74 @@ def test_soap_content_error(mocked_post, mocked_get, v1_service_wsdl, connector,
         status_code=200,
         headers={'Content-Type': 'text/xml'},
     )
     resp = app.get('/esirius-swi/test/get_all_indicators')
     assert resp.json['err'] == 1
     assert resp.json['err_desc'] == "'NoneType' object has no attribute 'getroottree'"
 
 
+@pytest.mark.parametrize(
+    'resource, time, status, value, unit, color',
+    [
+        (0, '00:01:39', 'closed', None, None, '#ff1800'),
+        (1, '-', 'closed', None, None, '#ff1800'),
+        (1, '00:00:00', 'open', 0, 'seconde', '#c3f000'),
+        (1, '00:00:03', 'open', 3, 'secondes', '#c3f000'),
+        (1, '00:01:39', 'open', 1, 'minute', '#c3f000'),
+        (1, '00:05:00', 'open', 5, 'minutes', '#ffff00'),
+        (1, '00:10:00', 'open', 10, 'minutes', '#ffd100'),
+        (1, '00:17:00', 'open', 17, 'minutes', '#ffd100'),
+        (1, '00:20:00', 'open', 20, 'minutes', '#ff5e00'),
+        (2, '00:40:00', 'open', 40, 'minutes', '#ff1800'),
+        (2, '00:42:00', 'open', 42, 'minutes', '#ff1800'),
+        (3, '01:22:22', 'open', 1, 'heure', '#ff1800'),
+    ],
+)
+def test_status(resource, time, status, value, unit, color):
+    raw_data = {
+        'name': "Braine-l'Alleud",
+        'cumulatedWaitingVisitorNumber': 6,
+        'resourceNumber': resource,
+        'estimatedAvgWaitingTime': time,
+    }
+    assert compute_status(raw_data) == {
+        'name': "Braine-l'Alleud",
+        'status': status,
+        'waiting_visitors': 6,
+        'focus': {'value': value, 'unit': unit, 'html_color': color},
+        'raw_data': raw_data,
+    }
+
+
 @mock.patch('passerelle.utils.Request.get')
 @mock.patch('passerelle.utils.Request.post')
 def test_get_all_indicator(mocked_post, mocked_get, v1_service_wsdl, connector, app):
     mocked_get.return_value = mock.Mock(content=v1_service_wsdl)
     mocked_post.return_value = mock.Mock(
         content=get_xml_file('get_all_indicators.xml'),
         status_code=200,
         headers={'Content-Type': 'text/xml'},
     )
     resp = app.get('/esirius-swi/test/get_all_indicators')
     assert resp.json['err'] == 0
     assert resp.json['data'] == [
         {
-            'cumulatedWaitingVisitorNumber': 6,
-            'estimatedAvgWaitingTime': '00:03:29',
-            'estimatedMaxWaitingTime': '-',
-            'estimatedWaitingTimeForNextTicket': '-',
             'name': "Braine-l'Alleud",
-            'realAvgWaitingTime': '00:03:51',
-            'realMaxWaitingTime': '00:06:42',
-            'resourceNumber': 9.000003,
-            'serviceWaitingIndicatorWSList': None,
-            'siteCode': 'site1',
-            'waitingVisitorNumber': None,
-            'weekHoursWS': None,
+            'status': 'open',
+            'waiting_visitors': 6,
+            'focus': {'value': 3, 'unit': 'minutes', 'html_color': '#c3f000'},
+            'raw_data': {
+                'cumulatedWaitingVisitorNumber': 6,
+                'estimatedAvgWaitingTime': '00:03:29',
+                'estimatedMaxWaitingTime': '-',
+                'estimatedWaitingTimeForNextTicket': '-',
+                'name': "Braine-l'Alleud",
+                'realAvgWaitingTime': '00:03:51',
+                'realMaxWaitingTime': '00:06:42',
+                'resourceNumber': 9.000003,
+                'serviceWaitingIndicatorWSList': None,
+                'siteCode': 'site1',
+                'waitingVisitorNumber': None,
+                'weekHoursWS': None,
+            },
         }
     ]
-- 
2.30.2

