Skip to content

Commit

Permalink
[model] Allow indoor location without indoor coords #54
Browse files Browse the repository at this point in the history
Fixes #54
  • Loading branch information
NoumbissiValere authored Jun 2, 2020
1 parent 357a398 commit a70b081
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 11 deletions.
14 changes: 8 additions & 6 deletions django_loci/base/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class UnvalidatedChoiceField(forms.ChoiceField):
"""
skips ChoiceField validation to allow custom options
"""

def validate(self, value):
super(forms.ChoiceField, self).validate(value)

Expand Down Expand Up @@ -188,7 +189,8 @@ def clean_floorplan(self):
floorplan_model = self.floorplan_model
type_ = self.cleaned_data.get('type')
floorplan_selection = self.cleaned_data.get('floorplan_selection')
if type_ != 'indoor' or floorplan_selection == 'new':
if type_ != 'indoor' or floorplan_selection == 'new' or \
not floorplan_selection:
return None
pk = self.cleaned_data['floorplan']
if not pk:
Expand All @@ -210,11 +212,10 @@ def clean(self):
if not is_mobile and type_ in ['outdoor', 'indoor']:
fields += ['location_selection', 'name', 'address', 'geometry']
if not is_mobile and type_ == 'indoor':
fields += ['floorplan_selection', 'floor', 'indoor']
if data.get('floorplan_selection') == 'existing':
fields.append('floorplan')
elif data.get('floorplan_selection') == 'new':
fields.append('image')
if data.get('image'):
fields += ['floor', 'indoor']
elif is_mobile and not data.get('location'):
data['name'] = ''
data['address'] = ''
Expand Down Expand Up @@ -259,8 +260,9 @@ def save(self, commit=True):
instance.location.name = str(self.instance.content_object)
instance.location.save()
# create or update floorplan
if data['type'] == 'indoor':
instance.floorplan = self._get_floorplan_instance()
floorplan = self._get_floorplan_instance()
if data['type'] == 'indoor' and floorplan.image:
instance.floorplan = floorplan
instance.floorplan.save()
# call super
return super().save(commit=True)
Expand Down
3 changes: 3 additions & 0 deletions django_loci/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ def _clean_indoor_position(self):
# allow empty values for outdoor locations
elif self.location.type != 'indoor' and self.indoor in [None, '']:
return
# allow empty values for indoor whose coordinates are not yet received
elif self.location.type == 'indoor' and self.indoor in [None, ''] and not self.floorplan:
return
# split indoor position
position = []
if self.indoor:
Expand Down
13 changes: 11 additions & 2 deletions django_loci/static/django-loci/js/loci.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*global
alert, confirm, console, Debug, opera, prompt, WSH
*/
/*
this JS is shared between:
- DeviceLocationForm
Expand Down Expand Up @@ -336,8 +339,14 @@ django.jQuery(function ($) {
$('#content-main form').submit(function (e) {
var indoorPosition = $('.field-indoor .floorplan-raw input').val();
if ($type.val() === 'indoor' && !indoorPosition) {
e.preventDefault();
alert(gettext('Please set the indoor position before saving'));
if ($floorplanImage[0].files.length !== 0 && !indoorPosition) {
alert('Please set the indoor position before saving');
e.preventDefault();
} else if ($floorplanImage[0].files.length === 0 && !indoorPosition) {
var confirmation = confirm('Do you want to save this indoor' +
'location without indoor coordinates?');
if (!confirmation) { e.preventDefault(); }
}
}
});

Expand Down
71 changes: 71 additions & 0 deletions django_loci/tests/base/test_admin_inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,74 @@ def test_missing_type_error(self):
})
r = self.client.post(reverse(self.add_url), params, follow=True)
self.assertContains(r, 'errors field-type')

def test_add_indoor_location_without_indoor_coords(self):
self._login_as_admin()
p = self._get_prefix()
params = self.params
params.update({
'name': 'test-add-indoor-location-without-coords',
'{0}-0-type'.format(p): 'indoor',
'{0}-0-location_selection'.format(p): 'new',
'{0}-0-location'.format(p): '',
'{0}-0-floorplan_selection'.format(p): 'new',
'{0}-0-floorplan'.format(p): '',
'{0}-0-floor'.format(p): '',
'{0}-0-image'.format(p): '',
'{0}-0-indoor'.format(p): '',
'{0}-0-id'.format(p): '',
})
r = self.client.post(reverse(self.add_url), params, follow=True)
self.assertNotContains(r, 'errors')
loc = self.location_model.objects.get(name=params['{0}-0-name'.format(p)])
self.assertEqual(loc.address, params['{0}-0-address'.format(p)])
self.assertEqual(loc.objectlocation_set.count(), 1)
self.assertEqual(self.location_model.objects.count(), 1)
self.assertEqual(self.floorplan_model.objects.count(), 0)
ol = loc.objectlocation_set.first()
self.assertEqual(ol.content_object.name, params['name'])
self.assertEqual(ol.location.type, 'indoor')
self.assertEqual(ol.indoor, '')

def test_add_indoor_location_without_coords(self):
self._login_as_admin()
p = self._get_prefix()
floorplan_file = open(self._floorplan_path, 'rb')
params = self.params
params.update({
'name': 'test-add-indoor-location-without-coords',
'{0}-0-type'.format(p): 'indoor',
'{0}-0-location_selection'.format(p): 'new',
'{0}-0-location'.format(p): '',
'{0}-0-floorplan_selection'.format(p): 'new',
'{0}-0-floorplan'.format(p): '',
'{0}-0-floor'.format(p): '1',
'{0}-0-image'.format(p): floorplan_file,
'{0}-0-indoor'.format(p): '',
'{0}-0-id'.format(p): '',
})
r = self.client.post(reverse(self.add_url), params, follow=True)
floorplan_file.close()
self.assertContains(r, 'error')
loc = self.location_model.objects.filter(name=params['{0}-0-name'.format(p)])
self.assertEqual(loc.count(), 0)

def test_add_indoor_location_without_floor(self):
p = self._get_prefix()
floorplan_file = open(self._floorplan_path, 'rb')
params = self.params
params.update({
'name': 'test-add-indoor-location-without-coords',
'{0}-0-type'.format(p): 'indoor',
'{0}-0-location_selection'.format(p): 'new',
'{0}-0-location'.format(p): '',
'{0}-0-floorplan_selection'.format(p): 'new',
'{0}-0-floorplan'.format(p): '',
'{0}-0-floor'.format(p): '',
'{0}-0-image'.format(p): floorplan_file,
'{0}-0-indoor'.format(p): '-100,100',
'{0}-0-id'.format(p): '',
})
r = self.client.post(reverse(self.add_url), params)
floorplan_file.close()
self.assertEqual(r.status_code, 302)
9 changes: 6 additions & 3 deletions django_loci/tests/base/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,15 @@ def test_invalid_indoor_position(self):
self._test_indoor_position_validation_error(ol)
ol.indoor = 'TOTALLY.WRONG'
self._test_indoor_position_validation_error(ol)
ol.indoor = '100.2300,-45.23454'
ol.full_clean()
# allow empty indoor for location whose indoor coordinates are not yet received
ol.indoor = ''
self._test_indoor_position_validation_error(ol)
ol.full_clean()
ol.save()
ol.indoor = None
self._test_indoor_position_validation_error(ol)
ol.indoor = '100.2300,-45.23454'
ol.full_clean()
ol.save()
# outdoor allows empty but not invalid values
loc.type = 'outdoor'
loc.full_clean()
Expand Down

0 comments on commit a70b081

Please sign in to comment.