0001-toulouse_smart-replace-by-_-in-field-varname-60870.patch
passerelle/contrib/toulouse_smart/models.py | ||
---|---|---|
175 | 175 |
data = {} |
176 | 176 |
cast = {'string': str, 'int': int, 'boolean': bool, 'item': str} |
177 | 177 |
for prop in intervention_type.get('properties') or []: |
178 |
name = prop['name'].lower()
|
|
179 |
if block.get(name): |
|
178 |
varname = slugify(prop['name']).replace('-', '_')
|
|
179 |
if block.get(varname):
|
|
180 | 180 |
try: |
181 |
data[prop['name']] = cast[prop['type']](block[name]) |
|
181 |
data[prop['name']] = cast[prop['type']](block[varname])
|
|
182 | 182 |
except ValueError: |
183 | 183 |
raise APIError( |
184 |
"cannot cast '%s' field to %s : '%s'" % (name, cast[prop['type']], block[name]),
|
|
184 |
"cannot cast '%s' field to %s : '%s'" % (varname, cast[prop['type']], block[varname]),
|
|
185 | 185 |
http_status=400, |
186 | 186 |
) |
187 | 187 |
elif prop['required']: |
188 |
raise APIError("'%s' field is required on '%s' block" % (name, slug), http_status=400) |
|
188 |
raise APIError("'%s' field is required on '%s' block" % (varname, slug), http_status=400)
|
|
189 | 189 | |
190 | 190 |
if self.wcs_requests.filter(wcs_form_api_url=post_data['form_api_url']): |
191 | 191 |
raise APIError( |
passerelle/contrib/toulouse_smart/templates/toulouse_smart/wcs_block.wcs | ||
---|---|---|
8 | 8 |
<label>{{ property.displayName }}</label> |
9 | 9 |
<type>{{ property.type }}</type> |
10 | 10 |
<required>{{ property.required }}</required> |
11 |
<varname>{{ property.name|slugify }}</varname>
|
|
11 |
<varname>{{ property.varname }}</varname>
|
|
12 | 12 |
<display_locations> |
13 | 13 |
<display_location>validation</display_location> |
14 | 14 |
<display_location>summary</display_location> |
passerelle/contrib/toulouse_smart/views.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import copy |
|
17 | 18 |
import hashlib |
18 | 19 |
import uuid |
19 | 20 |
import zipfile |
... | ... | |
42 | 43 | |
43 | 44 |
# generate file contents |
44 | 45 |
files = {} |
45 |
for intervention_type in self.object.get_intervention_types(): |
|
46 |
# do not alter the cached intervention_types |
|
47 |
intervention_types = copy.deepcopy(self.object.get_intervention_types()) |
|
48 |
for intervention_type in intervention_types: |
|
46 | 49 |
slug = slugify(intervention_type['name']) |
47 | 50 |
# only export intervention_type with properties |
48 | 51 |
if not intervention_type.get('properties'): |
... | ... | |
50 | 53 |
for prop in intervention_type['properties']: |
51 | 54 |
# generate a natural id for fields |
52 | 55 |
prop['id'] = make_id(slug + slugify(prop['name'])) |
56 |
prop['varname'] = slugify(prop['name']).replace('-', '_') |
|
53 | 57 |
# adapt types |
54 | 58 |
prop.setdefault('type', 'string') |
55 | 59 |
if prop['type'] == 'boolean': |
tests/test_toulouse_smart.py | ||
---|---|---|
139 | 139 |
<name>coin</name> |
140 | 140 |
<properties> |
141 | 141 |
<properties> |
142 |
<name>FIELD1</name>
|
|
142 |
<name>TYPE-OBJET</name>
|
|
143 | 143 |
<displayName>Champ 1</displayName> |
144 | 144 |
<type>string</type> |
145 | 145 |
<required>false</required> |
... | ... | |
174 | 174 |
'order': 1, |
175 | 175 |
'properties': [ |
176 | 176 |
{ |
177 |
'name': 'FIELD1',
|
|
177 |
'name': 'TYPE-OBJET',
|
|
178 | 178 |
'displayName': 'Champ 1', |
179 | 179 |
'required': False, |
180 | 180 |
'type': 'item', |
... | ... | |
220 | 220 |
assert [[td.text for td in tr.cssselect('td,th')] for tr in resp.pyquery('tr')] == [ |
221 | 221 |
["Nom du type d'intervention", 'Nom', 'Type', 'Requis', 'Valeur par défaut'], |
222 | 222 |
['1 - coin'], |
223 |
[None, 'FIELD1', 'item («Candélabre», «Mât», «Ne sait pas»)', '✘', 'Ne sait pas'],
|
|
223 |
[None, 'TYPE-OBJET', 'item («Candélabre», «Mât», «Ne sait pas»)', '✘', 'Ne sait pas'],
|
|
224 | 224 |
[None, 'FIELD2', 'int', '✔', None], |
225 | 225 |
['2 - empty'], |
226 | 226 |
] |
... | ... | |
236 | 236 |
<slug>coin</slug> |
237 | 237 |
<fields> |
238 | 238 |
<field> |
239 |
<id>038a8c2e-14de-4d4f-752f-496eb7fe90d7</id>
|
|
239 |
<id>522697a9-de01-b198-9e37-58c35718203a</id>
|
|
240 | 240 |
<label>Champ 1</label> |
241 | 241 |
<type>item</type> |
242 | 242 |
<required>False</required> |
243 |
<varname>field1</varname>
|
|
243 |
<varname>type_objet</varname>
|
|
244 | 244 |
<display_locations> |
245 | 245 |
<display_location>validation</display_location> |
246 | 246 |
<display_location>summary</display_location> |
... | ... | |
338 | 338 |
FIELDS_PAYLOAD = { |
339 | 339 |
'coin_raw': [ |
340 | 340 |
{ |
341 |
'field1': 'Candélabre',
|
|
342 |
'field1_raw': 'Candélabre',
|
|
341 |
'type_objet': 'Candélabre',
|
|
342 |
'type_objet_raw': 'Candélabre',
|
|
343 | 343 |
'field2': '42', |
344 | 344 |
}, |
345 | 345 |
], |
... | ... | |
369 | 369 |
'external_number': '42-2', |
370 | 370 |
'external_status': 'statut-1-wcs', |
371 | 371 |
'address': 'https://wcs.example.com/backoffice/management/foo/2/', |
372 |
'interventionData': {'FIELD1': 'Candélabre', 'FIELD2': 42},
|
|
372 |
'interventionData': {'TYPE-OBJET': 'Candélabre', 'FIELD2': 42},
|
|
373 | 373 |
'geom': {'type': 'Point', 'coordinates': [2.323349, 48.833708], 'crs': 'EPSG:4326'}, |
374 | 374 |
'interventionTypeId': '1234', |
375 | 375 |
'notificationUrl': 'http://testserver/toulouse-smart/test/update-intervention?uuid=%s' % str(UUID), |
... | ... | |
494 | 494 |
field_payload = { |
495 | 495 |
'coin_raw': [ |
496 | 496 |
{ |
497 |
'field1': 'Candélabre',
|
|
498 |
'field1_raw': 'Candélabre',
|
|
497 |
'type_objet': 'Candélabre',
|
|
498 |
'type_objet_raw': 'Candélabre',
|
|
499 | 499 |
'field2': None, |
500 | 500 |
}, |
501 | 501 |
], |
... | ... | |
514 | 514 |
field_payload = { |
515 | 515 |
'coin_raw': [ |
516 | 516 |
{ |
517 |
'field1': 'Candélabre',
|
|
518 |
'field1_raw': 'Candélabre',
|
|
517 |
'type_objet': 'Candélabre',
|
|
518 |
'type_objet_raw': 'Candélabre',
|
|
519 | 519 |
}, |
520 | 520 |
], |
521 | 521 |
} |
522 |
- |