0001-planitech-use-custom-fields-29127.patch
passerelle/contrib/planitech/migrations/0002_planitechconnector_custom_fields.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# Generated by Django 1.11.17 on 2019-01-08 11:22 |
|
3 |
from __future__ import unicode_literals |
|
4 | ||
5 |
from django.db import migrations |
|
6 |
import jsonfield.fields |
|
7 | ||
8 | ||
9 |
class Migration(migrations.Migration): |
|
10 | ||
11 |
dependencies = [ |
|
12 |
('planitech', '0001_initial'), |
|
13 |
] |
|
14 | ||
15 |
operations = [ |
|
16 |
migrations.AddField( |
|
17 |
model_name='planitechconnector', |
|
18 |
name='custom_fields', |
|
19 |
field=jsonfield.fields.JSONField(blank=True, null=True, verbose_name='Custom places fields'), |
|
20 |
), |
|
21 |
] |
passerelle/contrib/planitech/models.py | ||
---|---|---|
25 | 25 |
from django.utils import dateformat |
26 | 26 |
from django.utils import dateparse |
27 | 27 |
from django.utils.translation import ugettext_lazy as _ |
28 |
from jsonfield import JSONField |
|
28 | 29 |
from requests.exceptions import RequestException |
29 | 30 | |
30 | 31 |
from passerelle.base.models import BaseResource |
... | ... | |
151 | 152 |
max_length=128, verbose_name=_('Service password'), null=True, blank=True) |
152 | 153 |
verify_cert = models.BooleanField( |
153 | 154 |
default=True, verbose_name=_('Check HTTPS Certificate validity')) |
155 |
custom_fields = JSONField(_('Custom places fields'), blank=True, null=True) |
|
154 | 156 | |
155 | 157 |
category = _('Business Process Connectors') |
156 | 158 | |
... | ... | |
199 | 201 |
'identifier': place_id, 'label': place['label'] |
200 | 202 |
} |
201 | 203 | |
204 |
extensionAttributes = { |
|
205 |
'capacity': { |
|
206 |
'name': 'TOTCAP', |
|
207 |
'type': 'int' |
|
208 |
} |
|
209 |
} |
|
210 | ||
211 |
for custom_field in self.custom_fields: |
|
212 |
field_name = custom_field['name'] |
|
213 |
extensionAttributes[field_name] = { |
|
214 |
'name': field_name, |
|
215 |
'type': custom_field['type'] |
|
216 |
} |
|
217 | ||
202 | 218 |
data = self._call_planitech( |
203 | 219 |
self.requests.post, 'getPlacesInfo', |
204 | 220 |
{ |
205 | 221 |
"placeIdentifiers": [float(key) for key in ref.keys()], |
206 |
"extensionAttributes": { |
|
207 |
"capacity": { |
|
208 |
"name": "TOTCAP", |
|
209 |
"type": "int" |
|
210 |
} |
|
211 |
} |
|
222 |
"extensionAttributes": extensionAttributes |
|
212 | 223 |
} |
213 | 224 |
) |
214 | 225 |
for place in data['requestedPlaces']: |
226 | ||
215 | 227 |
place_id = int(place['identifier']) |
216 |
capacity = place.get('capacity') |
|
217 |
if capacity is not None: |
|
218 |
capacity = int(capacity) |
|
219 |
ref[place_id]['capacity'] = capacity |
|
220 | 228 |
ref[place_id]['street_number'] = place.get('streetNumber') |
221 | 229 |
ref[place_id]['address'] = place.get('address1') |
222 | 230 |
ref[place_id]['city'] = place.get('city') |
223 | 231 |
ref[place_id]['zipcode'] = place.get('zipCode') |
224 | 232 | |
233 |
for attr_name, attr_def in extensionAttributes.items(): |
|
234 |
attr_value = place.get(attr_name) |
|
235 |
if attr_value is not None and attr_def['type'] == 'int': |
|
236 |
attr_value = int(attr_value) |
|
237 |
ref[place_id][attr_name] = attr_value |
|
238 | ||
225 | 239 |
cache.set(cache_key, ref) |
226 | 240 |
return ref |
227 | 241 | |
... | ... | |
400 | 414 |
def getfreegaps( |
401 | 415 |
self, request, display, start_time, end_time, min_capacity=0, start_date=None, |
402 | 416 |
start_days=None, end_date=None, end_days=None, max_capacity=100000, weekdays=False, |
403 |
place_id=None): |
|
417 |
place_id=None, **kwargs):
|
|
404 | 418 | |
405 | 419 |
# Additional parameters check |
406 | 420 |
valid_displays = ['date', 'place', 'full'] |
... | ... | |
430 | 444 |
# Places restriction |
431 | 445 |
if place_id is not None: |
432 | 446 |
places_id = [int(place_id)] |
447 |
elif kwargs: |
|
448 |
places_filter = {} |
|
449 |
for p_name, p_value in kwargs.items(): |
|
450 |
if p_name.startswith('referential_'): |
|
451 |
p_name = p_name.replace('referential_', '') |
|
452 |
places_filter[p_name] = p_value |
|
453 | ||
454 |
places = self._get_places_referential() |
|
455 |
places_id = [] |
|
456 |
for place in places.values(): |
|
457 |
for filter_name, filter_value in places_filter.items(): |
|
458 |
for field in self.custom_fields: |
|
459 |
if filter_name == field['name']: |
|
460 |
if field['type'] == 'int': |
|
461 |
filter_value = int(filter_value) |
|
462 |
if place.get(filter_name) == filter_value: |
|
463 |
places_id.append(place['identifier']) |
|
433 | 464 |
else: |
434 | 465 |
places_id = self._get_places_by_capacity(int(min_capacity), int(max_capacity)) |
435 | 466 |
tests/test_planitech.py | ||
---|---|---|
73 | 73 |
api = ApiUser.objects.create(username='all', keytype='', key='') |
74 | 74 |
connector = PlanitechConnector.objects.create( |
75 | 75 |
url='http://example.planitech.com/', username='admin', password='admin', |
76 |
verify_cert=False, slug='slug-planitech') |
|
76 |
verify_cert=False, slug='slug-planitech', |
|
77 |
custom_fields=[{'name': 'some_custom_field', 'type': 'string'}]) |
|
77 | 78 |
obj_type = ContentType.objects.get_for_model(connector) |
78 | 79 |
AccessRight.objects.create( |
79 | 80 |
codename='can_access', apiuser=api, resource_type=obj_type, resource_pk=connector.pk) |
... | ... | |
219 | 220 |
'streetNumber': 1, 'address1': 'rue planitech', |
220 | 221 |
'city': 'thecity', 'zipCode': '00000' |
221 | 222 |
}, |
222 |
{'identifier': 2.0, 'capacity': 20.0} |
|
223 |
{ |
|
224 |
'identifier': 2.0, 'capacity': 20.0, |
|
225 |
'some_custom_field': 'Yes' |
|
226 |
} |
|
223 | 227 |
] |
224 | 228 |
} |
225 | 229 |
] |
... | ... | |
229 | 233 |
'2': { |
230 | 234 |
u'capacity': 20, u'label': u'salle 2', u'identifier': 2, |
231 | 235 |
'street_number': None, 'address': None, |
232 |
'city': None, 'zipcode': None |
|
236 |
'city': None, 'zipcode': None, 'some_custom_field': 'Yes'
|
|
233 | 237 |
}, |
234 | 238 |
'1': { |
235 | 239 |
u'capacity': 10, u'label': u'salle 1', u'identifier': 1, |
236 | 240 |
'street_number': 1, 'address': 'rue planitech', |
237 |
'city': 'thecity', 'zipcode': '00000' |
|
241 |
'city': 'thecity', 'zipcode': '00000', 'some_custom_field': None
|
|
238 | 242 |
} |
239 | 243 |
} |
240 | 244 |
assert response.json['data'] == expected_res |
... | ... | |
298 | 302 |
def freegaps_data(): |
299 | 303 |
referential = { |
300 | 304 |
2.0: { |
301 |
u'capacity': 20.0, u'label': u'salle 2', u'identifier': 2.0 |
|
305 |
u'capacity': 20.0, u'label': u'salle 2', u'identifier': 2.0, |
|
306 |
u'some_custom_field': u'Yes' |
|
302 | 307 |
}, |
303 | 308 |
1.0: { |
304 | 309 |
u'capacity': 10.0, u'label': u'salle 1', u'identifier': 1.0 |
... | ... | |
450 | 455 |
call_params = mock_call_planitech.call_args[0][2] |
451 | 456 |
assert 'reservationDays' not in call_params |
452 | 457 | |
458 |
# custom field restriction |
|
459 |
mock_call_planitech.reset_mock() |
|
460 |
response = app.get( |
|
461 |
'/planitech/slug-planitech/getfreegaps?start_time=11:00&&end_time=14:00' |
|
462 |
'&start_date=2018-11-11&referential_some_custom_field=Yes&display=place' |
|
463 |
) |
|
464 |
call_params = mock_call_planitech.call_args[0][2] |
|
465 |
assert call_params['placeIdentifiers'] == [2.0] |
|
466 | ||
453 | 467 |
# BAD REQUEST |
454 | 468 |
# bad date format |
455 | 469 |
response = app.get( |
456 |
- |