Projet

Général

Profil

0001-cityweb-add-cityweb-connector-15883.patch

Josué Kouka, 01 juin 2017 04:42

Télécharger (75,2 ko)

Voir les différences:

Subject: [PATCH] cityweb: add cityweb connector (#15883)

 passerelle/apps/cityweb/__init__.py                |   0
 passerelle/apps/cityweb/cityweb.py                 |  96 +++++++
 passerelle/apps/cityweb/mapping.py                 | 313 +++++++++++++++++++++
 passerelle/apps/cityweb/models.py                  | 146 ++++++++++
 .../cityweb/templates/cityweb/cityweb_detail.html  | 192 +++++++++++++
 passerelle/settings.py                             |   1 +
 tests/data/cityweb/cityweb.xsd                     | 181 ++++++++++++
 tests/data/cityweb/formdata_dec.json               | 183 ++++++++++++
 tests/data/cityweb/formdata_mar.json               | 242 ++++++++++++++++
 tests/data/cityweb/formdata_nais.json              | 184 ++++++++++++
 tests/test_cityweb.py                              | 190 +++++++++++++
 11 files changed, 1728 insertions(+)
 create mode 100644 passerelle/apps/cityweb/__init__.py
 create mode 100644 passerelle/apps/cityweb/cityweb.py
 create mode 100644 passerelle/apps/cityweb/mapping.py
 create mode 100644 passerelle/apps/cityweb/models.py
 create mode 100644 passerelle/apps/cityweb/templates/cityweb/cityweb_detail.html
 create mode 100644 tests/data/cityweb/cityweb.xsd
 create mode 100644 tests/data/cityweb/formdata_dec.json
 create mode 100644 tests/data/cityweb/formdata_mar.json
 create mode 100644 tests/data/cityweb/formdata_nais.json
 create mode 100644 tests/test_cityweb.py
passerelle/apps/cityweb/cityweb.py
1
# Copyright (C) 2017  Entr'ouvert
2
#
3
# This program is free software: you can redistribute it and/or modify it
4
# under the terms of the GNU Affero General Public License as published
5
# by the Free Software Foundation, either version 3 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU Affero General Public License for more details.
12
#
13
# You should have received a copy of the GNU Affero General Public License
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15

  
16
import os
17
from collections import OrderedDict
18

  
19
from dateutil.parser import parse as dateutil_parse
20

  
21
from django.core.files.storage import default_storage
22
from django.core.files.base import ContentFile
23

  
24
from passerelle.utils.jsonresponse import APIError
25
from passerelle.contrib.mdel.utils import ElementFactory, json_to_xml, zipdir, etree
26
from .mapping import MAPPING
27

  
28

  
29
ALLOWED_VALUES = {
30
    '_title_raw': ('M', 'Mme', 'Mlle'),  # {applicant_, concerned_, partner_}{father, mother}
31
    '_gender_raw': ('M', 'F', 'NA'),  # {applicant_, concerned_, partner_}{father, mother}
32
    'document_kind_raw': ('CPI', 'EXTAF', 'EXTSF', 'EXTPL'),
33
    'concerned_kind_raw': ('reconnu', 'auteur'),
34
    'event_kind_raw': ('NAI', 'MAR', 'REC', 'DEC'),
35
    'canal_raw': ('internet', 'guichet', 'courrier')
36
}
37

  
38

  
39
def is_value_allowed(key, value, allowed_values):
40
    if value not in allowed_values:
41
        raise APIError('Invalid value for %s: %s not in %s'
42
                       % (key, value, allowed_values))
43

  
44

  
45
class CivilStatusApplication(object):
46
    root_element = 'demandeEtatCivil'
47
    mapping = MAPPING
48
    namespace = 'http://tempuri.org/XMLSchema.xsd'
49

  
50
    def __init__(self, demand_id, data):
51
        self.application_id = demand_id
52
        self.data = self.validate(data)
53

  
54
    def validate(self, data):
55
        data['application_id'] = self.application_id
56
        data['application_date'] = data['receipt_time']
57
        applicant_is_concerned = data.pop('applicant_is_concerned', False)
58
        if applicant_is_concerned:
59
            data['concerned_kind'] = 'auteur'
60

  
61
        for key in data.keys():
62
            # set all dates to ISO format
63
            if '_date' in key and data.get(key):
64
                if key == 'application_date':
65
                    continue
66
                data[key] = dateutil_parse(data[key]).date().isoformat()
67
            # check value validity for key with value constraint
68
            for pattern, allowed_values in ALLOWED_VALUES.items():
69
                if key.endswith(pattern) and data.get(key):
70
                    is_value_allowed(pattern, data[key], allowed_values)
71
            # if the applicant is the concerned person, then all
72
            # applicant vars values are copied
73
            if key.startswith('applicant_') and applicant_is_concerned:
74
                if key == 'applicant_kind':
75
                    continue
76
                data[key.replace('applicant', 'concerned')] = data[key]
77
        return data
78

  
79
    @property
80
    def xml(self):
81
        elements = OrderedDict()
82
        for var, elt in self.mapping.items():
83
            if self.data.get(var):
84
                elements[elt] = self.data[var]
85

  
86
        etree.register_namespace('xs', 'http://tempuri.org/XMLSchema.xsd')
87
        root = ElementFactory(self.root_element, namespace=self.namespace)
88
        for key, value in elements.items():
89
            path = key.split('_')
90
            root.append(json_to_xml(path, value, root, namespace=self.namespace), allow_new=False)
91
        return root
92

  
93
    def save(self, path):
94
        filepath = os.path.join(path, self.application_id + '.xml')
95
        default_storage.save(filepath, ContentFile(self.xml.to_pretty_xml()))
96
        return zipdir(path)
passerelle/apps/cityweb/mapping.py
1
from collections import OrderedDict
2

  
3

  
4
MAPPING = OrderedDict((
5
    # <indentifiant>
6
    ("application_id", "identifiant"),
7

  
8
    # <demandeur>
9
    # <demandeur><qualiteDemandeur>
10
    ("applicant_kind", "demandeur_qualiteDemandeur"),
11
    # <demandeur><noms><nomDeFamille>
12
    ("applicant_names_family", "demandeur_individu_noms_nomDeFamille"),
13
    # <demandeur><noms><nomUsage>
14
    ("applicant_names_common", "demandeur_individu_noms_nomUsage"),
15
    # <demandeur><noms><usage>
16
    ("applicant_names_use", "demandeur_individu_noms_typeUsage"),
17
    # <demandeur><prenoms>
18
    ("applicant_firstnames", "demandeur_individu_prenoms"),
19
    # <demandeur><genre>
20
    ("applicant_title_raw", "demandeur_individu_genre"),
21
    # <demandeur><adresse><ligneAdr1>
22
    ("applicant_address_1", "demandeur_individu_adresse_ligneAdr1"),
23
    # <demandeur><adresse><ligneAdr2>
24
    ("applicant_address_2", "demandeur_individu_adresse_ligneAdr2"),
25
    # <demandeur><adresse><codePostal>
26
    ("applicant_address_zipcode", "demandeur_individu_adresse_codePostal"),
27
    # <demandeur><adresse><lieu><ville>
28
    ("applicant_address_city", "demandeur_individu_adresse_lieu_ville"),
29
    # <demandeur><adresse><lieu><province>
30
    ("applicant_address_district", "demandeur_individu_adresse_lieu_province"),
31
    # <demandeur><adresse><lieu><pays>
32
    ("applicant_address_country", "demandeur_individu_adresse_lieu_pays"),
33
    # <demandeur><adresse><mail>
34
    ("applicant_address_mail", "demandeur_individu_adresse_mail"),
35
    # <demandeur><adresse><tel>
36
    ("applicant_address_tel", "demandeur_individu_adresse_tel"),
37
    # <demandeur><sexe>
38
    ("applicant_gender_raw", "demandeur_individu_sexe"),
39
    # <demandeur><naissance><date>
40
    ("applicant_birth_date", "demandeur_individu_naissance_date"),
41
    # <demandeur><naissance><lieu><ville>
42
    ("applicant_birth_city", "demandeur_individu_naissance_lieu_ville"),
43
    # <demandeur><naissance><lieu><province>
44
    ("applicant_birth_district", "demandeur_individu_naissance_lieu_province"),
45
    # <demandeur><naissance><lieu><pays>
46
    ("applicant_birth_country", "demandeur_individu_naissance_lieu_pays"),
47
    # </demandeur>
48

  
49
    # <natureDocument>
50
    ("document_kind_raw", "natureDocument"),
51
    # <nbExemplaire>
52
    ("copies", "nbExemplaire"),
53
    # <dateDemande>
54
    ("application_date", "dateDemande"),
55

  
56
    # <evenement>
57

  
58

  
59
    #############################
60
    #   <EVENEMENT><INTERESSE>
61
    ##############################
62

  
63
    # <evenement><interesse><noms><nomDeFamille>
64
    ("concerned_names_family", "evenement_interesse_noms_nomDeFamille"),
65
    # <evenement><interesse><noms><nomUsage>
66
    ("concerned_names_common", "evenement_interesse_noms_nomUsage"),
67
    # <evenement><interesse><noms><usage>
68
    ("concerned_names_use", "evenement_interesse_noms_typeUsage"),
69
    # <evenement><interesse><prenoms>
70
    ("concerned_firstnames", "evenement_interesse_prenoms"),
71
    # <evenement><interesse><genre>
72
    ("concerned_title_raw", "evenement_interesse_genre"),
73
    # <evenement><interesse><adresse><ligneAdr1>
74
    ("concerned_address_1", "evenement_interesse_adresse_ligneAdr1"),
75
    # <evenement><interesse><adresse><ligneAdr2>
76
    ("concerned_address_2", "evenement_interesse_adresse_ligneAdr2"),
77
    # <evenement><interesse><adresse><codePostal>
78
    ("concerned_address_zipcode", "evenement_interesse_adresse_codePostal"),
79
    # <evenement><interesse><adresse><lieu><ville>
80
    ("concerned_address_city", "evenement_interesse_adresse_lieu_ville"),
81
    # <evenement><interesse><adresse><lieu><province>
82
    ("concerned_address_district", "evenement_interesse_adresse_lieu_province"),
83
    # <evenement><interesse><adresse><lieu><pays>
84
    ("concerned_address_country", "evenement_interesse_adresse_lieu_pays"),
85
    # <evenement><interesse><adresse><mail>
86
    ("concerned_address_mail", "evenement_interesse_adresse_mail"),
87
    # <evenement><interesse><adresse><tel>
88
    ("concerned_address_tel", "evenement_interesse_adresse_tel"),
89
    # <evenement><interesse><sexe>
90
    ("concerned_gender_raw", "evenement_interesse_sexe"),
91
    # <evenement><interesse><naissance><date>
92
    ("concerned_birth_date", "evenement_interesse_naissance_date"),
93
    # <evenement><interesse><naissance><lieu><ville>
94
    ("concerned_birth_city", "evenement_interesse_naissance_lieu_ville"),
95
    # <evenement><interesse><naissance><lieu><province>
96
    ("concerned_birth_district", "evenement_interesse_naissance_lieu_province"),
97
    # <evenement><interesse><naissance><lieu><pays>
98
    ("concerned_birth_country", "evenement_interesse_naissance_lieu_pays"),
99

  
100
    # # <evenement><interesse><pere><noms><nomDeFamille>
101
    # ("concerned_father_names_family", "evenement_interesse_pere_noms_nomDeFamille"),
102
    # # <evenement><interesse><pere><noms><nomUsage>
103
    # ("concerned_father_names_common", "evenement_interesse_pere_noms_nomUsage"),
104
    # # <evenement><interesse><pere><noms><usage>
105
    # ("concerned_father_names_use", "evenement_interesse_pere_noms_typeUsage"),
106
    # # <evenement><interesse><pere><prenoms>
107
    # ("concerned_father_firstnames", "evenement_interesse_pere_prenoms"),
108
    # # <evenement><interesse><pere><genre>
109
    # ("concerned_father_title_raw", "evenement_interesse_pere_genre"),
110
    # # <evenement><interesse><pere><adresse><ligneAdr1>
111
    # ("concerned_father_address_1", "evenement_interesse_pere_adresse_ligneAdr1"),
112
    # # <evenement><interesse><pere><adresse><ligneAdr2>
113
    # ("concerned_father_address_2", "evenement_interesse_pere_adresse_ligneAdr2"),
114
    # # <evenement><interesse><pere><adresse><codePostal>
115
    # ("concerned_father_address_zipcode", "evenement_interesse_pere_adresse_codePostal"),
116
    # # <evenement><interesse><pere><adresse><lieu><ville>
117
    # ("concerned_father_address_city", "evenement_interesse_pere_adresse_lieu_ville"),
118
    # # <evenement><interesse><pere><adresse><lieu><province>
119
    # ("concerned_father_address_district", "evenement_interesse_pere_adresse_lieu_province"),
120
    # # <evenement><interesse><pere><adresse><lieu><pays>
121
    # ("concerned_father_address_country", "evenement_interesse_pere_adresse_lieu_pays"),
122
    # # <evenement><interesse><pere><adresse><mail>
123
    # ("concerned_father_address_mail", "evenement_interesse_pere_adresse_mail"),
124
    # # <evenement><interesse><pere><adresse><tel>
125
    # ("concerned_father_address_tel", "evenement_interesse_pere_adresse_tel"),
126
    # # <evenement><interesse><pere><sexe>
127
    # ("concerned_father_gender_raw", "evenement_interesse_pere_sexe"),
128
    # # <evenement><interesse><pere><naissance><date>
129
    # ("concerned_father_birth_date", "evenement_interesse_pere_naissance_date"),
130
    # # <evenement><interesse><pere><naissance><lieu><ville>
131
    # ("concerned_father_birth_city", "evenement_interesse_pere_naissance_lieu_ville"),
132
    # # <evenement><interesse><pere><naissance><lieu><province>
133
    # ("concerned_father_birth_district", "evenement_interesse_pere_naissance_lieu_province"),
134
    # # <evenement><interesse><pere><naissance><lieu><pays>
135
    # ("concerned_father_birth_country", "evenement_interesse_pere_naissance_lieu_pays"),
136

  
137
    # # <evenement><interesse><mere><mere><noms><nomDeFamille>
138
    # ("concerned_mother_names_family", "evenement_interesse_mere_noms_nomDeFamille"),
139
    # # <evenement><interesse><mere><mere><noms><nomUsage>
140
    # ("concerned_mother_names_common", "evenement_interesse_mere_noms_nomUsage"),
141
    # # <evenement><interesse><mere><mere><noms><usage>
142
    # ("concerned_mother_names_use", "evenement_interesse_mere_noms_typeUsage"),
143
    # # <evenement><interesse><mere><mere><prenoms>
144
    # ("concerned_mother_firstnames", "evenement_interesse_mere_prenoms"),
145
    # # <evenement><interesse><mere><mere><genre>
146
    # ("concerned_mother_title_raw", "evenement_interesse_mere_genre"),
147
    # # <evenement><interesse><mere><mere><adresse><ligneAdr1>
148
    # ("concerned_mother_address_1", "evenement_interesse_mere_adresse_ligneAdr1"),
149
    # # <evenement><interesse><mere><mere><adresse><ligneAdr2>
150
    # ("concerned_mother_address_2", "evenement_interesse_mere_adresse_ligneAdr2"),
151
    # # <evenement><interesse><mere><mere><adresse><codePostal>
152
    # ("concerned_mother_address_zipcode", "evenement_interesse_mere_adresse_codePostal"),
153
    # # <evenement><interesse><mere><mere><adresse><lieu><ville>
154
    # ("concerned_mother_address_city", "evenement_interesse_mere_adresse_lieu_ville"),
155
    # # <evenement><interesse><mere><mere><adresse><lieu><province>
156
    # ("concerned_mother_address_district", "evenement_interesse_mere_adresse_lieu_province"),
157
    # # <evenement><interesse><mere><mere><adresse><lieu><pays>
158
    # ("concerned_mother_address_country", "evenement_interesse_mere_adresse_lieu_pays"),
159
    # # <evenement><interesse><mere><mere><adresse><mail>
160
    # ("concerned_mother_address_mail", "evenement_interesse_mere_adresse_mail"),
161
    # # <evenement><interesse><mere><mere><adresse><tel>
162
    # ("concerned_mother_address_tel", "evenement_interesse_mere_adresse_tel"),
163
    # # <evenement><interesse><mere><mere><sexe>
164
    # ("concerned_mother_gender_raw", "evenement_interesse_mere_sexe"),
165
    # # <evenement><interesse><mere><mere><naissance><date>
166
    # ("concerned_mother_birth_date", "evenement_interesse_mere_naissance_date"),
167
    # # <evenement><interesse><mere><mere><naissance><lieu><ville>
168
    # ("concerned_mother_birth_city", "evenement_interesse_mere_naissance_lieu_ville"),
169
    # # <evenement><interesse><mere><mere><naissance><lieu><province>
170
    # ("concerned_mother_birth_district", "evenement_interesse_mere_naissance_lieu_province"),
171
    # # <evenement><interesse><mere><mere><naissance><lieu><pays>
172
    # ("concerned_mother_birth_country", "evenement_interesse_mere_naissance_lieu_pays"),
173

  
174

  
175

  
176
    #############################
177
    #   <EVENEMENT><CONJOINT>
178
    ##############################
179
    # <evenement><conjoint>
180
    # <evenement><conjoint><noms><nomDeFamille>
181
    ("partner_names_family", "evenement_conjoint_noms_nomDeFamille"),
182
    # <evenement><conjoint><noms><nomUsage>
183
    ("partner_names_common", "evenement_conjoint_noms_nomUsage"),
184
    # <evenement><conjoint><noms><usage>
185
    ("partner_names_use", "evenement_conjoint_noms_typeUsage"),
186
    # <evenement><conjoint><prenoms>
187
    ("partner_firstnames", "evenement_conjoint_prenoms"),
188
    # <evenement><conjoint><genre>
189
    ("partner_title_raw", "evenement_conjoint_genre"),
190
    # <evenement><conjoint><adresse><ligneAdr1>
191
    ("partner_address_1", "evenement_conjoint_adresse_ligneAdr1"),
192
    # <evenement><conjoint><adresse><ligneAdr2>
193
    ("partner_address_2", "evenement_conjoint_adresse_ligneAdr2"),
194
    # <evenement><conjoint><adresse><codePostal>
195
    ("partner_address_zipcode", "evenement_conjoint_adresse_codePostal"),
196
    # <evenement><conjoint><adresse><lieu><ville>
197
    ("partner_address_city", "evenement_conjoint_adresse_lieu_ville"),
198
    # <evenement><conjoint><adresse><lieu><province>
199
    ("partner_address_district", "evenement_conjoint_adresse_lieu_province"),
200
    # <evenement><conjoint><adresse><lieu><pays>
201
    ("partner_address_country", "evenement_conjoint_adresse_lieu_pays"),
202
    # <evenement><conjoint><adresse><mail>
203
    ("partner_address_mail", "evenement_conjoint_adresse_mail"),
204
    # <evenement><conjoint><adresse><tel>
205
    ("partner_address_tel", "evenement_conjoint_adresse_tel"),
206
    # <evenement><conjoint><sexe>
207
    ("partner_gender_raw", "evenement_conjoint_sexe"),
208
    # <evenement><conjoint><naissance><date>
209
    ("partner_birth_date", "evenement_conjoint_naissance_date"),
210
    # <evenement><conjoint><naissance><lieu><ville>
211
    ("partner_birth_city", "evenement_conjoint_naissance_lieu_ville"),
212
    # <evenement><conjoint><naissance><lieu><province>
213
    ("partner_birth_district", "evenement_conjoint_naissance_lieu_province"),
214
    # <evenement><conjoint><naissance><lieu><pays>
215
    ("partner_birth_country", "evenement_conjoint_naissance_lieu_pays"),
216

  
217
    # # <evenement><conjoint><pere><noms><nomDeFamille>
218
    # ("partner_father_names_family", "evenement_conjoint_pere_noms_nomDeFamille"),
219
    # # <evenement><conjoint><pere><noms><nomUsage>
220
    # ("partner_father_names_common", "evenement_conjoint_pere_noms_nomUsage"),
221
    # # <evenement><conjoint><pere><noms><usage>
222
    # ("partner_father_names_use", "evenement_conjoint_pere_noms_typeUsage"),
223
    # # <evenement><conjoint><pere><prenoms>
224
    # ("partner_father_firstnames", "evenement_conjoint_pere_prenoms"),
225
    # # <evenement><conjoint><pere><genre>
226
    # ("partner_father_title_raw", "evenement_conjoint_pere_genre"),
227
    # # <evenement><conjoint><pere><adresse><ligneAdr1>
228
    # ("partner_father_address_1", "evenement_conjoint_pere_adresse_ligneAdr1"),
229
    # # <evenement><conjoint><pere><adresse><ligneAdr2>
230
    # ("partner_father_address_2", "evenement_conjoint_pere_adresse_ligneAdr2"),
231
    # # <evenement><conjoint><pere><adresse><codePostal>
232
    # ("partner_father_address_zipcode", "evenement_conjoint_pere_adresse_codePostal"),
233
    # # <evenement><conjoint><pere><adresse><lieu><ville>
234
    # ("partner_father_address_city", "evenement_conjoint_pere_adresse_lieu_ville"),
235
    # # <evenement><conjoint><pere><adresse><lieu><province>
236
    # ("partner_father_address_district", "evenement_conjoint_pere_adresse_lieu_province"),
237
    # # <evenement><conjoint><pere><adresse><lieu><pays>
238
    # ("partner_father_address_country", "evenement_conjoint_pere_adresse_lieu_pays"),
239
    # # <evenement><conjoint><pere><adresse><mail>
240
    # ("partner_father_address_mail", "evenement_conjoint_pere_adresse_mail"),
241
    # # <evenement><conjoint><pere><adresse><tel>
242
    # ("partner_father_address_tel", "evenement_conjoint_pere_adresse_tel"),
243
    # # <evenement><conjoint><pere><sexe>
244
    # ("partner_father_gender_raw", "evenement_conjoint_pere_sexe"),
245
    # # <evenement><conjoint><pere><naissance><date>
246
    # ("partner_father_birth_date", "evenement_conjoint_pere_naissance_date"),
247
    # # <evenement><conjoint><pere><naissance><lieu><ville>
248
    # ("partner_father_birth_city", "evenement_conjoint_pere_naissance_lieu_ville"),
249
    # # <evenement><conjoint><pere><naissance><lieu><province>
250
    # ("partner_father_birth_district", "evenement_conjoint_pere_naissance_lieu_province"),
251
    # # <evenement><conjoint><pere><naissance><lieu><pays>
252
    # ("partner_father_birth_country", "evenement_conjoint_pere_naissance_lieu_pays"),
253

  
254
    # # <evenement><conjoint><mere><mere><noms><nomDeFamille>
255
    # ("partner_mother_names_family", "evenement_conjoint_mere_noms_nomDeFamille"),
256
    # # <evenement><conjoint><mere><mere><noms><nomUsage>
257
    # ("partner_mother_names_common", "evenement_conjoint_mere_noms_nomUsage"),
258
    # # <evenement><conjoint><mere><mere><noms><usage>
259
    # ("partner_mother_names_use", "evenement_conjoint_mere_noms_typeUsage"),
260
    # # <evenement><conjoint><mere><mere><prenoms>
261
    # ("partner_mother_firstnames", "evenement_conjoint_mere_prenoms"),
262
    # # <evenement><conjoint><mere><mere><genre>
263
    # ("partner_mother_title_raw", "evenement_conjoint_mere_genre"),
264
    # # <evenement><conjoint><mere><mere><adresse><ligneAdr1>
265
    # ("partner_mother_address_1", "evenement_conjoint_mere_adresse_ligneAdr1"),
266
    # # <evenement><conjoint><mere><mere><adresse><ligneAdr2>
267
    # ("partner_mother_address_2", "evenement_conjoint_mere_adresse_ligneAdr2"),
268
    # # <evenement><conjoint><mere><mere><adresse><codePostal>
269
    # ("partner_mother_address_zipcode", "evenement_conjoint_mere_adresse_codePostal"),
270
    # # <evenement><conjoint><mere><mere><adresse><lieu><ville>
271
    # ("partner_mother_address_city", "evenement_conjoint_mere_adresse_lieu_ville"),
272
    # # <evenement><conjoint><mere><mere><adresse><lieu><province>
273
    # ("partner_mother_address_district", "evenement_conjoint_mere_adresse_lieu_province"),
274
    # # <evenement><conjoint><mere><mere><adresse><lieu><pays>
275
    # ("partner_mother_address_country", "evenement_conjoint_mere_adresse_lieu_pays"),
276
    # # <evenement><conjoint><mere><mere><adresse><mail>
277
    # ("partner_mother_address_mail", "evenement_conjoint_mere_adresse_mail"),
278
    # # <evenement><conjoint><mere><mere><adresse><tel>
279
    # ("partner_mother_address_tel", "evenement_conjoint_mere_adresse_tel"),
280
    # # <evenement><conjoint><mere><mere><sexe>
281
    # ("partner_mother_gender_raw", "evenement_conjoint_mere_sexe"),
282
    # # <evenement><conjoint><mere><mere><naissance><date>
283
    # ("partner_mother_birth_date", "evenement_conjoint_mere_naissance_date"),
284
    # # <evenement><conjoint><mere><mere><naissance><lieu><ville>
285
    # ("partner_mother_birth_city", "evenement_conjoint_mere_naissance_lieu_ville"),
286
    # # <evenement><conjoint><mere><mere><naissance><lieu><province>
287
    # ("partner_mother_birth_district", "evenement_conjoint_mere_naissance_lieu_province"),
288
    # # <evenement><conjoint><mere><mere><naissance><lieu><pays>
289
    # ("partner_mother_birth_country", "evenement_conjoint_mere_naissance_lieu_pays"),
290

  
291
    # <evenement><natureEvenement>
292
    ("event_kind_raw", "evenement_natureEvenement"),
293
    # <evenement><typeInteresse>
294
    ("concerned_kind", "evenement_typeInteresse"),
295
    # <evenement><lieuEvenement><dateEvenement><dateDebut>
296
    ("event_date_start", "evenement_dateEvenement_dateDebut"),
297
    # <evenement><lieuEvenement><dateEvenement><dateFin>
298
    ("event_date_end", "evenement_dateEvenement_dateFin"),
299
    # <evenement><lieuEvenement><ville>
300
    ("event_city", "evenement_lieuEvenement_ville"),
301
    # <evenement><lieuEvenement><province>
302
    ("event_district", "evenement_lieuEvenement_province"),
303
    # <evenement><lieuEvenement><pays>
304
    ("event_country", "evenement_lieuEvenement_pays"),
305
    # </evenement>
306

  
307
    # <motif>
308
    ("reason", "motif"),
309
    # <origine>
310
    ("canal", "origine"),
311
    # <commentaire>
312
    ("comment", "commentaire"),
313
))
passerelle/apps/cityweb/models.py
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2017  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
import os
18
import json
19

  
20
from dateutil.parser import parse as dateutil_parse
21

  
22
from django.db import models
23
from django.utils.translation import ugettext_lazy as _
24
from django.core.files.storage import default_storage
25

  
26
from passerelle.base.models import BaseResource
27
from passerelle.utils.api import endpoint
28
from passerelle.utils.jsonresponse import APIError
29
from passerelle.contrib.mdel.utils import flatten_payload
30

  
31
from .cityweb import CivilStatusApplication
32

  
33

  
34
EVENTS_KIND = [
35
    {"id": "NAI", "text": "Naissance"},
36
    {"id": "MAR", "text": "Mariage"},
37
    {"id": "REC", "text": "Reconnaissance"},
38
    {"id": "DEC", "text": "Décès"}
39
]
40

  
41
GENDERS = [
42
    {"id": "M", "text": "Homme"},
43
    {"id": "F", "text": "Femme"},
44
    {"id": "NA", "text": "Autre"}
45
]
46

  
47
TITLES = [
48
    {"id": "M", "text": "Monsieur"},
49
    {"id": "Mme", "text": "Madame"},
50
    {"id": "Mlle", "text": "Mademoiselle"}
51
]
52

  
53
DOCUMENTS_KIND = [
54
    {"id": "CPI", "text": "Copie intégrale"},
55
    {"id": "EXTAF", "text": "Extrait avec filiation"},
56
    {"id": "EXTSF", "text": "Extrait sans filiation"},
57
    {"id": "EXTPL", "text": "Extrait plurilingue"}
58
]
59

  
60
CONCERNED = [
61
    {"id": "reconnu", "text": "Reconnu"},
62
    {"id": "auteur", "text": "Auteur"}
63
]
64

  
65
CHANNELS = [
66
    {"id": "internet", "text": "Internet"},
67
    {"id": "guichet", "text": "Guichet"},
68
    {"id": "courrier", "text": "Courrier"}
69
]
70

  
71

  
72
class CityWeb(BaseResource):
73
    category = _('Business Process Connectors')
74

  
75
    class Meta:
76
        verbose_name = "CityWeb - Demande d'acte d'état civil"
77

  
78
    @classmethod
79
    def get_verbose_name(cls):
80
        return cls._meta.verbose_name
81

  
82
    @endpoint(serializer_type='json-api', perm='can_access', methods=['post'])
83
    def create(self, request, *args, **kwargs):
84
        formdata = json.loads(request.body)
85
        formdata.update(flatten_payload(formdata.pop('fields'), formdata.pop('extra')))
86
        # check mandatory keys
87
        for key in ('display_id', 'receipt_time', 'event_kind_raw'):
88
            if key not in formdata:
89
                raise APIError('<%s> is required' % key)
90

  
91
        attrs = {
92
            'demand_id': '%s-%s' % (formdata['display_id'], formdata['event_kind_raw']),
93
            'kind': formdata['event_kind_raw'], 'resource': self,
94
            'received_at': dateutil_parse(formdata['receipt_time'])}
95

  
96
        demand, created = Demand.objects.get_or_create(**attrs)
97
        result = demand.create(formdata)
98
        return {'demand_id': result}
99

  
100
    @endpoint(serializer_type='json-api', perm='can_access')
101
    def titles(self, request):
102
        return TITLES
103

  
104
    @endpoint(serializer_type='json-api', perm='can_access')
105
    def genders(self, request):
106
        return GENDERS
107

  
108
    @endpoint(serializer_type='json-api', perm='can_access')
109
    def concerned(self, request):
110
        return CONCERNED
111

  
112
    @endpoint(serializer_type='json-api', perm='can_access')
113
    def channels(self, request):
114
        return CHANNELS
115

  
116
    @endpoint(name='events-kind', serializer_type='json-api', perm='can_access')
117
    def events_kind(self, request, without=''):
118
        return [item for item in EVENTS_KIND
119
                if item.get('id') not in without.split(',')]
120

  
121
    @endpoint(name='documents-kind', serializer_type='json-api', perm='can_access')
122
    def documents_kind(self, request, without=''):
123
        return [item for item in DOCUMENTS_KIND
124
                if item.get('id') not in without.split(',')]
125

  
126

  
127
class Demand(models.Model):
128
    created_at = models.DateTimeField(auto_now_add=True)
129
    updated_at = models.DateTimeField(auto_now=True)
130
    received_at = models.DateTimeField()
131
    resource = models.ForeignKey(CityWeb)
132
    demand_id = models.CharField(max_length=32, primary_key=True)
133
    kind = models.CharField(max_length=32)
134

  
135
    def __unicode__(self):
136
        return '%s - %s - %s' % (self.resource.slug, self.demand_id)
137

  
138
    @property
139
    def filepath(self):
140
        return os.path.join(
141
            default_storage.path('cityweb'), self.resource.slug, self.demand_id)
142

  
143
    def create(self, data):
144
        application = CivilStatusApplication(self.demand_id, data)
145
        application.save(self.filepath)
146
        return self.demand_id
passerelle/apps/cityweb/templates/cityweb/cityweb_detail.html
1
{% extends "passerelle/manage/service_view.html" %}
2
{% load i18n passerelle %}
3

  
4
{% block endpoints %}
5
<ul>
6
    <li>
7
        <h4>{%trans 'Create Demand'%}</h4>
8
        {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="create" as create %}
9
        <p> <strong>POST</strong> <a href="{{create}}">{{create}}</a></p>
10
        <ul>
11
            <li>application_id / display_id</li>
12
            <li>application_application_date / receipt_time</li>
13
            <!-- Applicant var -->
14
            <li>applicant_kind ('avocat', 'notaire', 'père', 'mère')</li>
15
            <li>applicant_names_family</li>
16
            <li>applicant_names_common</li>
17
            <li>applicant_names_use (maiden name, widow name)</li>
18
            <li>applicant_firstnames</li>
19
            <li>applicant_title ('M', 'Mme', 'Mlle')</li>
20
            <li>applicant_gender ('M', 'F', 'NA')</li>
21
            <li>applicant_address_1</li>
22
            <li>applicant_address_2</li>
23
            <li>applicant_address_zipcode</li>
24
            <li>applicant_address_city</li>
25
            <li>applicant_address_district</li>
26
            <li>applicant_address_country</li>
27
            <li>applicant_address_mail</li>
28
            <li>applicant_address_tel</li>
29
            <li>applicant_birth_date</li>
30
            <li>applicant_birth_city</li>
31
            <li>applicant_birth_district</li>
32
            <li>applicant_birth_country</li>
33
            <li>applicant_kind</li>
34
            <!--  -->
35
            <li>document_kind ('CPI', 'EXTAF', 'EXTSF', 'EXTPL')</li>
36
            <li>copies</li>
37
            <!-- Event Concerned -->
38
            <li>applicant_is_concerned (true, false)</li>
39
            <li>concerned_kind ('reconnu', 'auteur')</li>
40
            <li>concerned_names_family</li>
41
            <li>concerned_names_common</li>
42
            <li>concerned_names_use (maiden name, widow)</li>
43
            <li>concerned_firstnames</li>
44
            <li>concerned_title</li>
45
            <li>concerned_gender</li>
46
            <li>concerned_address_1</li>
47
            <li>concerned_address_2</li>
48
            <li>concerned_address_zipcode</li>
49
            <li>concerned_address_city</li>
50
            <li>concerned_address_district</li>
51
            <li>concerned_address_country</li>
52
            <li>concerned_address_mail</li>
53
            <li>concerned_address_tel</li>
54
            <li>concerned_birth_date</li>
55
            <li>concerned_birth_city</li>
56
            <li>concerned_birth_district</li>
57
            <li>concerned_birth_country</li>
58
            <!-- Concerned father -->
59
            <li>concerned_father_names_family</li>
60
            <li>concerned_father_names_common</li>
61
            <li>concerned_father_names_use (maiden name, widow)</li>
62
            <li>concerned_father_firstnames</li>
63
            <li>concerned_father_title</li>
64
            <li>concerned_father_gender</li>
65
            <li>concerned_father_address_1</li>
66
            <li>concerned_father_address_2</li>
67
            <li>concerned_father_address_zipcode</li>
68
            <li>concerned_father_address_city</li>
69
            <li>concerned_father_address_district</li>
70
            <li>concerned_father_address_country</li>
71
            <li>concerned_father_address_mail</li>
72
            <li>concerned_father_address_tel</li>
73
            <li>concerned_father_birth_date</li>
74
            <li>concerned_father_birth_city</li>
75
            <li>concerned_father_birth_district</li>
76
            <li>concerned_father_birth_country</li>
77
            <!-- Concerned mother -->
78
            <li>concerned_mother_names_family</li>
79
            <li>concerned_mother_names_common</li>
80
            <li>concerned_mother_names_use (maiden name, widow)</li>
81
            <li>concerned_mother_firstnames</li>
82
            <li>concerned_mother_title</li>
83
            <li>concerned_mother_gender</li>
84
            <li>concerned_mother_address_1</li>
85
            <li>concerned_mother_address_2</li>
86
            <li>concerned_mother_address_zipcode</li>
87
            <li>concerned_mother_address_city</li>
88
            <li>concerned_mother_address_district</li>
89
            <li>concerned_mother_address_country</li>
90
            <li>concerned_mother_address_mail</li>
91
            <li>concerned_mother_address_tel</li>
92
            <li>concerned_mother_birth_date</li>
93
            <li>concerned_mother_birth_city</li>
94
            <li>concerned_mother_birth_district</li>
95
            <li>concerned_mother_birth_country</li>
96
            <!-- Partner -->
97
            <li>partner_names_family</li>
98
            <li>partner_names_common</li>
99
            <li>partner_names_use (maiden name, widow)</li>
100
            <li>partner_firstnames</li>
101
            <li>partner_title</li>
102
            <li>partner_gender</li>
103
            <li>partner_address_1</li>
104
            <li>partner_address_2</li>
105
            <li>partner_address_zipcode</li>
106
            <li>partner_address_city</li>
107
            <li>partner_address_district</li>
108
            <li>partner_address_country</li>
109
            <li>partner_address_mail</li>
110
            <li>partner_address_tel</li>
111
            <li>partner_birth_date</li>
112
            <li>partner_birth_city</li>
113
            <li>partner_birth_district</li>
114
            <li>partner_birth_country</li>
115
            <!-- Partner father -->
116
            <li>partner_father_kind</li>
117
            <li>partner_father_names_family</li>
118
            <li>partner_father_names_common</li>
119
            <li>partner_father_names_use (maiden name, widow)</li>
120
            <li>partner_father_firstnames</li>
121
            <li>partner_father_title</li>
122
            <li>partner_father_gender</li>
123
            <li>partner_father_address_1</li>
124
            <li>partner_father_address_2</li>
125
            <li>partner_father_address_zipcode</li>
126
            <li>partner_father_address_city</li>
127
            <li>partner_father_address_district</li>
128
            <li>partner_father_address_country</li>
129
            <li>partner_father_address_mail</li>
130
            <li>partner_father_address_tel</li>
131
            <li>partner_father_birth_date</li>
132
            <li>partner_father_birth_city</li>
133
            <li>partner_father_birth_district</li>
134
            <li>partner_father_birth_country</li>
135
            <!-- Partner mother -->
136
            <li>partner_mother_kind</li>
137
            <li>partner_mother_names_family</li>
138
            <li>partner_mother_names_common</li>
139
            <li>partner_mother_names_use (maiden name, widow)</li>
140
            <li>partner_mother_firstnames</li>
141
            <li>partner_mother_title</li>
142
            <li>partner_mother_gender</li>
143
            <li>partner_mother_address_1</li>
144
            <li>partner_mother_address_2</li>
145
            <li>partner_mother_address_zipcode</li>
146
            <li>partner_mother_address_city</li>
147
            <li>partner_mother_address_district</li>
148
            <li>partner_mother_address_country</li>
149
            <li>partner_mother_address_mail</li>
150
            <li>partner_mother_address_tel</li>
151
            <li>partner_mother_birth_date</li>
152
            <li>partner_mother_birth_city</li>
153
            <li>partner_mother_birth_district</li>
154
            <li>partner_mother_birth_country</li>
155
            <!--  -->
156
            <li>event_kind ('NAI', 'DEC', 'MAR', 'REC')</li>
157
            <!-- Event date -->
158
            <li>event_date_start</li>
159
            <li>event_date_end</li>
160
            <!-- Event place -->
161
            <li>event_city</li>
162
            <li>event_district</li>
163
            <li>event_country</li>
164
            <li>reason</li>
165
            <li>canal ('internet', 'guichet', 'courrier')</li>
166
            <li>comment</li>
167
        </ul>
168
    </li>
169
    <li>
170
        <h4>{%trans 'Data Sources'%}</h4>
171
        {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="titles" as get_titles %}
172
        <p><strong>GET</strong> <a href="{{get_title}}">{{get_titles}}</a></p>
173
        {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="genders" as get_genders %}
174
        <p><strong>GET</strong> <a href="{{get_title}}">{{get_genders}}</a></p>
175
        {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="concerned" as get_concerned %}
176
        <p><strong>GET</strong> <a href="{{get_title}}">{{get_concerned}}</a></p>
177
        {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="channels" as get_channels %}
178
        <p><strong>GET</strong> <a href="{{get_title}}">{{get_channels}}</a></p>
179
        {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="events-kind" as get_events_kind %}
180
        <p><strong>GET</strong> <a href="{{get_events_kind}}?without=DEC,REC">{{get_events_kind}}?without=DEC,REC</a></p>
181
        {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="documents-kind" as get_events_kind %}
182
        <p><strong>GET</strong> <a href="{{get_documents_kind}}?without=EXTPL">{{get_documents_kind}}?without=EXTPL</a></p>
183
    </li>
184
</ul>
185
{% endblock %}
186

  
187
{% block security %}
188
<p>
189
  {% trans 'Access is limited to the following API users:' %}
190
</p>
191
{% access_rights_table resource=object permission='can_access' %}
192
{% endblock %}
passerelle/settings.py
113 113
    'passerelle.apps.opengis',
114 114
    'passerelle.apps.airquality',
115 115
    'passerelle.apps.okina',
116
    'passerelle.apps.cityweb',
116 117
    # backoffice templates and static
117 118
    'gadjo',
118 119
)
tests/data/cityweb/cityweb.xsd
1
<?xml version="1.0" encoding="utf-8"?>
2
<!-- edited with XMLSpy v2005 U (http://www.xmlspy.com) by judlin (digitech) -->
3
<xs:schema xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:mstns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified">
4
	<xs:element name="demandeEtatCivil">
5
		<xs:annotation>
6
			<xs:documentation>Root element</xs:documentation>
7
		</xs:annotation>
8
		<xs:complexType>
9
			<xs:sequence>
10
				<xs:element name="identifiant" type="xs:string" />
11
				<xs:element name="demandeur" type="demandeurType" minOccurs="0">
12
					<xs:annotation>
13
						<xs:documentation>utile si différent de l'interessé</xs:documentation>
14
					</xs:annotation>
15
				</xs:element>
16
				<xs:element name="natureDocument" type="natureDocumentType">
17
					<xs:annotation>
18
						<xs:documentation>copie intégrale, extrait avec ou sans	filiation, plurilingue</xs:documentation>
19
					</xs:annotation>
20
				</xs:element>
21
				<xs:element name="nbExemplaire" type="xs:int" minOccurs="0" />
22
				<xs:element name="dateDemande" type="xs:dateTime" />
23
				<xs:element name="evenement" type="evenementType" />
24
				<xs:element name="motif" type="xs:string" minOccurs="0" />
25
				<xs:element name="origine" type="origineECType" minOccurs="0">
26
					<xs:annotation>
27
						<xs:documentation>origine de la demande pour l'état civil : courrier, guichet ou internet</xs:documentation>
28
					</xs:annotation>
29
				</xs:element>
30
				<xs:element name="commentaire" type="xs:string" minOccurs="0" >
31
					<xs:annotation>
32
						<xs:documentation>champ commentaire</xs:documentation>
33
					</xs:annotation>
34
				</xs:element>
35
			</xs:sequence>
36
			<xs:attribute name="version" type="xs:string" default="1.0"/>
37
		</xs:complexType>
38
	</xs:element>
39
	<xs:simpleType name="natureEvenementType">
40
		<xs:annotation>
41
			<xs:documentation>Naissance, mariage, décès, reconnaissance</xs:documentation>
42
		</xs:annotation>
43
		<xs:restriction base="xs:string">
44
			<xs:enumeration value="NAI"/>
45
			<xs:enumeration value="DEC"/>
46
			<xs:enumeration value="MAR"/>
47
			<xs:enumeration value="REC"/>
48
		</xs:restriction>
49
	</xs:simpleType>
50
	<xs:complexType name="individuType">
51
		<xs:sequence>
52
			<xs:element name="noms" type="nomsType"/>
53
			<xs:element name="prenoms" type="xs:string" minOccurs="0"/>
54
			<xs:element name="genre" type="genreType" minOccurs="0"/>
55
			<xs:element name="adresse" type="adresseType" minOccurs="0"/>
56
			<xs:element name="sexe" type="sexeType" minOccurs="0"/>
57
			<xs:element name="pere" type="individuType" minOccurs="0"/>
58
			<xs:element name="mere" type="individuType" minOccurs="0"/>
59
			<xs:element name="naissance" type="naissanceType" minOccurs="0"/>
60
		</xs:sequence>
61
	</xs:complexType>
62
	<xs:complexType name="demandeurType">
63
		<xs:annotation>
64
			<xs:documentation>Informations sur le demandeur</xs:documentation>
65
		</xs:annotation>
66
		<xs:sequence>
67
			<xs:element name="qualiteDemandeur" type="xs:string">
68
				<xs:annotation>
69
					<xs:documentation>avocat, notaire, père, mère...</xs:documentation>
70
				</xs:annotation>
71
			</xs:element>
72
			<xs:element name="individu" type="individuType"/>
73
		</xs:sequence>
74
	</xs:complexType>
75
	<xs:simpleType name="sexeType">
76
		<xs:annotation>
77
			<xs:documentation>permet de gérer le sexe indeterminé</xs:documentation>
78
		</xs:annotation>
79
		<xs:restriction base="xs:string">
80
			<xs:enumeration value="F"/>
81
			<xs:enumeration value="M"/>
82
			<xs:enumeration value="NA"/>
83
		</xs:restriction>
84
	</xs:simpleType>
85
	<xs:simpleType name="genreType">
86
		<xs:restriction base="xs:string">
87
			<xs:enumeration value="M"/>
88
			<xs:enumeration value="Mme"/>
89
			<xs:enumeration value="Mlle"/>
90
		</xs:restriction>
91
	</xs:simpleType>
92
	<xs:complexType name="adresseType">
93
		<xs:sequence>
94
			<xs:element name="ligneAdr1" type="xs:string" minOccurs="0"/>
95
			<xs:element name="ligneAdr2" type="xs:string" minOccurs="0"/>
96
			<xs:element name="codePostal" type="xs:string" minOccurs="0"/>
97
			<xs:element name="lieu" type="lieuType"/>
98
			<xs:element name="mail" type="xs:string" minOccurs="0"/>
99
			<xs:element name="tel" type="xs:string" minOccurs="0"/>
100
		</xs:sequence>
101
	</xs:complexType>
102
	<xs:simpleType name="typeInteresseType">
103
		<xs:restriction base="xs:string">
104
			<xs:enumeration value="reconnu"/>
105
			<xs:enumeration value="auteur"/>
106
		</xs:restriction>
107
	</xs:simpleType>
108
	<xs:simpleType name="natureDocumentType">
109
		<xs:restriction base="xs:string">
110
			<xs:enumeration value="CPI"/>
111
			<xs:enumeration value="EXTAF"/>
112
			<xs:enumeration value="EXTSF"/>
113
			<xs:enumeration value="EXTPL"/>
114
		</xs:restriction>
115
	</xs:simpleType>
116
	<xs:simpleType name="origineECType">
117
		<xs:restriction base="xs:string">
118
			<xs:enumeration value="internet"/>
119
			<xs:enumeration value="guichet"/>
120
			<xs:enumeration value="courrier"/>
121
		</xs:restriction>
122
	</xs:simpleType>
123
	<xs:complexType name="evenementType">
124
		<xs:sequence>
125
			<xs:element name="interesse" type="individuType"/>
126
			<xs:element name="conjoint" type="individuType" minOccurs="0">
127
				<xs:annotation>
128
					<xs:documentation>Seulement pour les mariages</xs:documentation>
129
				</xs:annotation>
130
			</xs:element>
131
			<xs:element name="natureEvenement" type="natureEvenementType">
132
				<xs:annotation>
133
					<xs:documentation>naissance, mariage, décès, reconnaissance</xs:documentation>
134
				</xs:annotation>
135
			</xs:element>
136
			<xs:element name="typeInteresse" type="typeInteresseType" minOccurs="0">
137
				<xs:annotation>
138
					<xs:documentation>necessaire pour les reconnaissances seulement, l'interessé pouvant etre le parent ou le reconnu, il faut donc préciser.</xs:documentation>
139
				</xs:annotation>
140
			</xs:element>
141
			<xs:element name="dateEvenement" type="dateEvenementType"/>
142
			<xs:element name="lieuEvenement" type="lieuType"/>
143
		</xs:sequence>
144
	</xs:complexType>
145
	<xs:complexType name="nomsType">
146
		<xs:sequence>
147
			<xs:element name="nomDeFamille" type="xs:string"/>
148
			<xs:element name="nomUsage" type="xs:string" minOccurs="0"/>
149
			<xs:element name="typeUsage" type="xs:string" minOccurs="0">
150
				<xs:annotation>
151
					<xs:documentation>précission sur le nom d'usage: nom d'épouse, veuve, d'usage...</xs:documentation>
152
				</xs:annotation>
153
			</xs:element>
154
		</xs:sequence>
155
	</xs:complexType>
156
	<xs:complexType name="naissanceType">
157
		<xs:sequence>
158
			<xs:element name="date" type="dateCiviqueType"/>
159
			<xs:element name="lieu" type="lieuType" minOccurs="0"/>
160
		</xs:sequence>
161
	</xs:complexType>
162
	<xs:complexType name="lieuType">
163
		<xs:sequence>
164
			<xs:element name="ville" type="xs:string"/>
165
			<xs:element name="province" type="xs:string" minOccurs="0"/>
166
			<xs:element name="pays" type="xs:string" minOccurs="0"/>
167
		</xs:sequence>
168
	</xs:complexType>
169
	<xs:complexType name="dateEvenementType">
170
		<xs:sequence>
171
			<xs:element name="dateDebut" type="xs:date"/>
172
			<xs:element name="dateFin" type="xs:date" minOccurs="0"/>
173
		</xs:sequence>
174
	</xs:complexType>
175
	<xs:simpleType name="dateCiviqueType">
176
		<xs:annotation>
177
			<xs:documentation>Permet de gérer les dates incomplètes</xs:documentation>
178
		</xs:annotation>
179
		<xs:union memberTypes="xs:date xs:gYear xs:gYearMonth"/>
180
	</xs:simpleType>
181
</xs:schema>
tests/data/cityweb/formdata_dec.json
1
{
2
    "criticality_level": 0,
3
    "display_id": "17-1",
4
    "display_name": "Demande d'un acte de d\u00e9c\u00e8s #17-1",
5
    "evolution": [
6
        {
7
            "status": "2",
8
            "time": "2016-10-20T14:41:20Z",
9
            "who": {
10
                "email": "chelsea@whatever.com",
11
                "id": "2",
12
                "name": "chelsea"
13
            }
14
        }
15
    ],
16
    "extra": {
17
        "code_insee": "54395",
18
        "code_postal": "54000",
19
        "event_city": "Nantes",
20
        "event_country": "France",
21
        "event_kind": "Deces",
22
        "event_kind_raw": "DEC"
23
    },
24
    "fields": {
25
        "applicant_address_1": "37 Rue du Cheval Blanc",
26
        "applicant_address_2": "",
27
        "applicant_address_city": "Nancy",
28
        "applicant_address_country": "France",
29
        "applicant_address_district": "Meurthe-et-Moselle",
30
        "applicant_address_mail": "chelsea@whatever.com",
31
        "applicant_address_tel": "+33 6 55 44 22 11",
32
        "applicant_address_zipcode": "54000",
33
        "applicant_birth_city": "Nantes",
34
        "applicant_birth_country": "France",
35
        "applicant_birth_date": "11/07/1989",
36
        "applicant_birth_district": "Loire-Atlantique",
37
        "applicant_firstnames": "Kim Chelsea",
38
        "applicant_gender": "Femelle",
39
        "applicant_gender_raw": "F",
40
        "applicant_kind": "personne concern\u00e9",
41
        "applicant_names_common": "Whatever",
42
        "applicant_names_family": "Whatever",
43
        "applicant_names_use": "nom d'epouse",
44
        "applicant_title": "Madame",
45
        "applicant_title_raw": "Mme",
46
        "canal": "internet",
47
        "concerned_address_1": "",
48
        "concerned_address_2": "",
49
        "concerned_address_city": "",
50
        "concerned_address_country": "",
51
        "concerned_address_district": "",
52
        "concerned_address_mail": "",
53
        "concerned_address_tel": "",
54
        "concerned_address_zipcode": "",
55
        "concerned_birth_city": "Harare",
56
        "concerned_birth_country": "Zimbabwe",
57
        "concerned_birth_date": "1980-02-29",
58
        "concerned_birth_district": "",
59
        "concerned_father_address_1": "21 Bvd Henri Orion",
60
        "concerned_father_address_2": "Batiment A, Apt 18",
61
        "concerned_father_address_city": "Nantes",
62
        "concerned_father_address_country": "France",
63
        "concerned_father_address_district": "Loite-Atlantique",
64
        "concerned_father_address_mail": "",
65
        "concerned_father_address_tel": "",
66
        "concerned_father_address_zipcode": "44000",
67
        "concerned_father_birth_city": "Orvault",
68
        "concerned_father_birth_country": "France",
69
        "concerned_father_birth_date": "11-04-1955",
70
        "concerned_father_birth_district": "Loire-Atlantique",
71
        "concerned_father_firstnames": "John Oliver",
72
        "concerned_father_gender": "Male",
73
        "concerned_father_gender_raw": "M",
74
        "concerned_father_names_common": "Smith",
75
        "concerned_father_names_family": "Smith",
76
        "concerned_father_names_use": "Smith",
77
        "concerned_father_title": "Monsieur",
78
        "concerned_father_title_raw": "M",
79
        "concerned_firstnames": "Kevin",
80
        "concerned_gender_raw": "M",
81
        "concerned_mother_address_1": "21 Bvd Henri Orion",
82
        "concerned_mother_address_2": "Batiment A, Apt 18",
83
        "concerned_mother_address_city": "Nantes",
84
        "concerned_mother_address_country": "France",
85
        "concerned_mother_address_district": "Loite-Atlantique",
86
        "concerned_mother_address_mail": "kim@gmail.com",
87
        "concerned_mother_address_tel": "",
88
        "concerned_mother_address_zipcode": "44000",
89
        "concerned_mother_birth_city": "Seoul",
90
        "concerned_mother_birth_country": "South Korea",
91
        "concerned_mother_birth_date": "10-05-1960",
92
        "concerned_mother_birth_district": "",
93
        "concerned_mother_firstnames": "Kim",
94
        "concerned_mother_gender": "",
95
        "concerned_mother_kind": "",
96
        "concerned_mother_names_common": "Smith",
97
        "concerned_mother_names_family": "Smith",
98
        "concerned_mother_names_use": "nom d'\u00e9pouse",
99
        "concerned_mother_title": "Mme",
100
        "concerned_names_common": "Whatever",
101
        "concerned_names_family": "Whatever",
102
        "concerned_names_use": "",
103
        "concerned_title_raw": "M",
104
        "copies": "1",
105
        "document_kind": "Copie Integrale",
106
        "document_kind_raw": "CPI",
107
        "event_date_end": "",
108
        "event_date_start": "2012-07-14",
109
        "event_district": "Val-de-Marne",
110
        "reason": "They are just messy"
111
    },
112
    "id": "demande-d-un-acte-de-deces/1",
113
    "last_update_time": "2016-10-20T14:41:20Z",
114
    "receipt_time": "2016-10-20T14:41:20Z",
115
    "roles": {
116
        "_receiver": [
117
            {
118
                "allows_backoffice_access": true,
119
                "details": "",
120
                "emails": [],
121
                "emails_to_members": false,
122
                "id": "22",
123
                "name": "Etat civil Acte",
124
                "slug": "etat-civil-acte",
125
                "text": "Etat civil Acte"
126
            }
127
        ],
128
        "actions": [
129
            {
130
                "allows_backoffice_access": true,
131
                "details": "",
132
                "emails": [],
133
                "emails_to_members": false,
134
                "id": "3",
135
                "name": "agent",
136
                "slug": "agent",
137
                "text": "agent"
138
            }
139
        ],
140
        "concerned": [
141
            {
142
                "allows_backoffice_access": true,
143
                "details": "",
144
                "emails": [],
145
                "emails_to_members": false,
146
                "id": "3",
147
                "name": "agent",
148
                "slug": "agent",
149
                "text": "agent"
150
            },
151
            {
152
                "allows_backoffice_access": true,
153
                "details": "",
154
                "emails": [],
155
                "emails_to_members": false,
156
                "id": "22",
157
                "name": "Etat civil Acte",
158
                "slug": "etat-civil-acte",
159
                "text": "Etat civil Acte"
160
            }
161
        ]
162
    },
163
    "submission": {
164
        "backoffice": false,
165
        "channel": "web"
166
    },
167
    "url": "http://wcs.debian.local/demande-d-un-acte-de-deces/1/",
168
    "user": {
169
        "email": "chelsea@whatever.com",
170
        "id": "2",
171
        "name": "chelsea"
172
    },
173
    "workflow": {
174
        "fields": {
175
            "aec_type": null,
176
            "aec_type_raw": null
177
        },
178
        "status": {
179
            "id": "2",
180
            "name": "new"
181
        }
182
    }
183
}
tests/data/cityweb/formdata_mar.json
1
{
2
    "criticality_level": 0,
3
    "display_id": "16-1",
4
    "display_name": "Demande d'un acte de mariage #16-1",
5
    "evolution": [
6
        {
7
            "status": "2",
8
            "time": "2016-10-20T15:17:05Z",
9
            "who": {
10
                "email": "chelsea@whatever.com",
11
                "id": "2",
12
                "name": "chelsea"
13
            }
14
        }
15
    ],
16
    "extra": {
17
        "code_insee": "54395",
18
        "code_postal": "54000",
19
        "event_city": "Nantes",
20
        "event_country": "France",
21
        "event_kind": "Mariage",
22
        "event_kind_raw": "MAR"
23
    },
24
    "fields": {
25
        "applicant_is_concerned": true,
26
        "applicant_address_1": "37 Rue du Cheval Blanc",
27
        "applicant_address_2": "",
28
        "applicant_address_city": "Nancy",
29
        "applicant_address_country": "France",
30
        "applicant_address_district": "Meurthe-et-Moselle",
31
        "applicant_address_mail": "chelsea@whatever.com",
32
        "applicant_address_tel": "+33 6 55 44 22 11",
33
        "applicant_address_zipcode": "54000",
34
        "applicant_birth_city": "Nantes",
35
        "applicant_birth_country": "France",
36
        "applicant_birth_date": "11/07/1989",
37
        "applicant_birth_district": "Loire-Atlantique",
38
        "applicant_firstnames": "Kim Chelsea",
39
        "applicant_gender": "Femelle",
40
        "applicant_gender_raw": "F",
41
        "applicant_kind": "personne concern\u00e9",
42
        "applicant_names_common": "Whatever",
43
        "applicant_names_family": "Whatever",
44
        "applicant_names_use": "nom d'epouse",
45
        "applicant_title": "Madame",
46
        "applicant_title_raw": "Mme",
47
        "canal": "internet",
48
        "concerned_address_1": "",
49
        "concerned_address_2": "",
50
        "concerned_address_city": "",
51
        "concerned_address_country": "",
52
        "concerned_address_district": "",
53
        "concerned_address_mail": "",
54
        "concerned_address_tel": "",
55
        "concerned_address_zipcode": "",
56
        "concerned_birth_city": "",
57
        "concerned_birth_country": "",
58
        "concerned_birth_date": "",
59
        "concerned_birth_district": "",
60
        "concerned_father_address_1": "21 Bvd Henri Orion",
61
        "concerned_father_address_2": "Batiment A, Apt 18",
62
        "concerned_father_address_city": "Nantes",
63
        "concerned_father_address_country": "France",
64
        "concerned_father_address_district": "Loite-Atlantique",
65
        "concerned_father_address_mail": "",
66
        "concerned_father_address_tel": "",
67
        "concerned_father_address_zipcode": "44000",
68
        "concerned_father_birth_city": "Orvault",
69
        "concerned_father_birth_country": "France",
70
        "concerned_father_birth_date": "11-04-1955",
71
        "concerned_father_birth_district": "Loire-Atlantique",
72
        "concerned_father_firstnames": "John Oliver",
73
        "concerned_father_gender": "Male",
74
        "concerned_father_gender_raw": "M",
75
        "concerned_father_names_common": "Smith",
76
        "concerned_father_names_family": "Smith",
77
        "concerned_father_names_use": "Smith",
78
        "concerned_father_title": "Monsieur",
79
        "concerned_father_title_raw": "M",
80
        "concerned_firstnames": "",
81
        "concerned_gender": "",
82
        "concerned_kind": "",
83
        "concerned_mother_address_1": "21 Bvd Henri Orion",
84
        "concerned_mother_address_2": "Batiment A, Apt 18",
85
        "concerned_mother_address_city": "Nantes",
86
        "concerned_mother_address_country": "France",
87
        "concerned_mother_address_district": "Loite-Atlantique",
88
        "concerned_mother_address_mail": "kim@gmail.com",
89
        "concerned_mother_address_tel": "",
90
        "concerned_mother_address_zipcode": "44000",
91
        "concerned_mother_birth_city": "Seoul",
92
        "concerned_mother_birth_country": "South Korea",
93
        "concerned_mother_birth_date": "10-05-1960",
94
        "concerned_mother_birth_district": "",
95
        "concerned_mother_firstnames": "Kim",
96
        "concerned_mother_gender": "",
97
        "concerned_mother_kind": "",
98
        "concerned_mother_names_common": "Smith",
99
        "concerned_mother_names_family": "Smith",
100
        "concerned_mother_names_use": "nom d'\u00e9pouse",
101
        "concerned_mother_title": "Mme",
102
        "concerned_names_common": "",
103
        "concerned_names_family": "",
104
        "concerned_names_use": "",
105
        "concerned_title": "",
106
        "copies": "2",
107
        "document_kind": "Copie Integrale",
108
        "document_kind_raw": "CPI",
109
        "event_date_end": "",
110
        "event_date_start": "2012-07-14",
111
        "event_district": "Val-de-Marne",
112
        "partner_address_1": "37 Rue du cheval Blanc",
113
        "partner_address_2": "",
114
        "partner_address_city": "Nancy",
115
        "partner_address_country": "France",
116
        "partner_address_district": "Meurthe-et-Moselle",
117
        "partner_address_mail": "kevin@lost.com",
118
        "partner_address_tel": "",
119
        "partner_address_zipcode": "54000",
120
        "partner_birth_city": "Paris",
121
        "partner_birth_country": "France",
122
        "partner_birth_date": "25-11-1985",
123
        "partner_birth_district": "",
124
        "partner_father_address_1": "West 12th Avenue",
125
        "partner_father_address_2": "",
126
        "partner_father_address_city": "Vancouver",
127
        "partner_father_address_country": "Canada",
128
        "partner_father_address_district": "British Columbia",
129
        "partner_father_address_mail": "",
130
        "partner_father_address_tel": "",
131
        "partner_father_address_zipcode": "BC V5Y 1V4",
132
        "partner_father_birth_city": "Vancouver",
133
        "partner_father_birth_country": "Canada",
134
        "partner_father_birth_date": "23-02-1957",
135
        "partner_father_birth_district": "British Columbia",
136
        "partner_father_firstnames": "Eric Eliot",
137
        "partner_father_gender": "Male",
138
        "partner_father_gender_raw": "M",
139
        "partner_father_names_common": "Whatever",
140
        "partner_father_names_family": "Whatever",
141
        "partner_father_names_use": "",
142
        "partner_father_title": "Monsieur",
143
        "partner_father_title_raw": "M",
144
        "partner_firstnames": "Kevin Johnny",
145
        "partner_gender": "Male",
146
        "partner_gender_raw": "M",
147
        "partner_mother_address_1": "",
148
        "partner_mother_address_2": "",
149
        "partner_mother_address_city": "",
150
        "partner_mother_address_country": "",
151
        "partner_mother_address_district": "",
152
        "partner_mother_address_mail": "",
153
        "partner_mother_address_tel": "",
154
        "partner_mother_address_zipcode": "",
155
        "partner_mother_birth_city": "Sao Paolo",
156
        "partner_mother_birth_country": "Brazil",
157
        "partner_mother_birth_date": "11/06/1962",
158
        "partner_mother_birth_district": "",
159
        "partner_mother_firstnames": "Clara",
160
        "partner_mother_gender": "F",
161
        "partner_mother_names_common": "Whatever",
162
        "partner_mother_names_family": "Da Silva",
163
        "partner_mother_names_use": "nom d'epouse",
164
        "partner_mother_title": "Madame",
165
        "partner_mother_title_raw": "M",
166
        "partner_names_common": "Whatever",
167
        "partner_names_family": "Whatever",
168
        "partner_title": "M",
169
        "reason": "They are just messy"
170
    },
171
    "id": "demande-d-un-acte-de-mariage/1",
172
    "last_update_time": "2016-10-20T15:17:05Z",
173
    "receipt_time": "2016-10-20T15:17:05Z",
174
    "roles": {
175
        "_receiver": [
176
            {
177
                "allows_backoffice_access": true,
178
                "details": "",
179
                "emails": [],
180
                "emails_to_members": false,
181
                "id": "22",
182
                "name": "Etat civil Acte",
183
                "slug": "etat-civil-acte",
184
                "text": "Etat civil Acte"
185
            }
186
        ],
187
        "actions": [
188
            {
189
                "allows_backoffice_access": true,
190
                "details": "",
191
                "emails": [],
192
                "emails_to_members": false,
193
                "id": "3",
194
                "name": "agent",
195
                "slug": "agent",
196
                "text": "agent"
197
            }
198
        ],
199
        "concerned": [
200
            {
201
                "allows_backoffice_access": true,
202
                "details": "",
203
                "emails": [],
204
                "emails_to_members": false,
205
                "id": "3",
206
                "name": "agent",
207
                "slug": "agent",
208
                "text": "agent"
209
            },
210
            {
211
                "allows_backoffice_access": true,
212
                "details": "",
213
                "emails": [],
214
                "emails_to_members": false,
215
                "id": "22",
216
                "name": "Etat civil Acte",
217
                "slug": "etat-civil-acte",
218
                "text": "Etat civil Acte"
219
            }
220
        ]
221
    },
222
    "submission": {
223
        "backoffice": false,
224
        "channel": "web"
225
    },
226
    "url": "http://wcs.debian.local/demande-d-un-acte-de-mariage/1/",
227
    "user": {
228
        "email": "chelsea@whatever.com",
229
        "id": "2",
230
        "name": "chelsea"
231
    },
232
    "workflow": {
233
        "fields": {
234
            "aec_type": null,
235
            "aec_type_raw": null
236
        },
237
        "status": {
238
            "id": "2",
239
            "name": "new"
240
        }
241
    }
242
}
tests/data/cityweb/formdata_nais.json
1
{
2
    "criticality_level": 0,
3
    "display_id": "15-4",
4
    "display_name": "Demande d'un acte de naissance #15-4",
5
    "evolution": [
6
        {
7
            "status": "2",
8
            "time": "2016-10-19T14:00:19Z",
9
            "who": {
10
                "email": "chelsea@whatever.com",
11
                "id": "2",
12
                "name": "chelsea"
13
            }
14
        }
15
    ],
16
    "extra": {
17
        "code_insee": "54395",
18
        "code_postal": "54000",
19
        "event_city": "Nantes",
20
        "event_country": "France",
21
        "event_kind": "Naissance",
22
        "event_kind_raw": "NAI"
23
    },
24
    "fields": {
25
        "applicant_address_1": "37 Rue du Cheval Blanc",
26
        "applicant_address_2": "",
27
        "applicant_address_city": "Nancy",
28
        "applicant_address_country": "France",
29
        "applicant_address_district": "Meurthe-et-Moselle",
30
        "applicant_address_mail": "chelsea@whatever.com",
31
        "applicant_address_tel": "+33 6 55 44 22 11",
32
        "applicant_address_zipcode": "54000",
33
        "applicant_birth_city": "Nantes",
34
        "applicant_birth_country": "France",
35
        "applicant_birth_date": "11/07/1989",
36
        "applicant_birth_district": "Loire-Atlantique",
37
        "applicant_firstnames": "Kim Chelsea",
38
        "applicant_gender": "Femelle",
39
        "applicant_gender_raw": "F",
40
        "applicant_is_concerned": "true",
41
        "applicant_kind": "personne concern\u00e9",
42
        "applicant_names_common": "Whatever",
43
        "applicant_names_family": "Whatever",
44
        "applicant_names_use": "nom d'epouse",
45
        "applicant_title": "Madame",
46
        "applicant_title_raw": "Mme",
47
        "canal": "internet",
48
        "concerned_address_1": "",
49
        "concerned_address_2": "",
50
        "concerned_address_city": "",
51
        "concerned_address_country": "",
52
        "concerned_address_district": "",
53
        "concerned_address_mail": "",
54
        "concerned_address_tel": "",
55
        "concerned_address_zipcode": "",
56
        "concerned_birth_city": "Harare",
57
        "concerned_birth_country": "Zimbabwe",
58
        "concerned_birth_date": "1980-02-29",
59
        "concerned_birth_district": "",
60
        "concerned_father_address_1": "21 Bvd Henri Orion",
61
        "concerned_father_address_2": "Batiment A, Apt 18",
62
        "concerned_father_address_city": "Nantes",
63
        "concerned_father_address_country": "France",
64
        "concerned_father_address_district": "Loite-Atlantique",
65
        "concerned_father_address_mail": "",
66
        "concerned_father_address_tel": "",
67
        "concerned_father_address_zipcode": "44000",
68
        "concerned_father_birth_city": "Orvault",
69
        "concerned_father_birth_country": "France",
70
        "concerned_father_birth_date": "11-04-1955",
71
        "concerned_father_birth_district": "Loire-Atlantique",
72
        "concerned_father_firstnames": "John Oliver",
73
        "concerned_father_gender": "Male",
74
        "concerned_father_gender_raw": "M",
75
        "concerned_father_names_common": "Smith",
76
        "concerned_father_names_family": "Smith",
77
        "concerned_father_names_use": "Smith",
78
        "concerned_father_title": "Monsieur",
79
        "concerned_father_title_raw": "M",
80
        "concerned_firstnames": "Kevin",
81
        "concerned_gender_raw": "M",
82
        "concerned_mother_address_1": "21 Bvd Henri Orion",
83
        "concerned_mother_address_2": "Batiment A, Apt 18",
84
        "concerned_mother_address_city": "Nantes",
85
        "concerned_mother_address_country": "France",
86
        "concerned_mother_address_district": "Loite-Atlantique",
87
        "concerned_mother_address_mail": "kim@gmail.com",
88
        "concerned_mother_address_tel": "",
89
        "concerned_mother_address_zipcode": "44000",
90
        "concerned_mother_birth_city": "Seoul",
91
        "concerned_mother_birth_country": "South Korea",
92
        "concerned_mother_birth_date": "10-05-1960",
93
        "concerned_mother_birth_district": "",
94
        "concerned_mother_firstnames": "Kim",
95
        "concerned_mother_gender": "",
96
        "concerned_mother_kind": "",
97
        "concerned_mother_names_common": "Smith",
98
        "concerned_mother_names_family": "Smith",
99
        "concerned_mother_names_use": "nom d'\u00e9pouse",
100
        "concerned_mother_title": "Mme",
101
        "concerned_names_common": "Whatever",
102
        "concerned_names_family": "Whatever",
103
        "concerned_names_use": "",
104
        "concerned_title_raw": "M",
105
        "copies": "1",
106
        "document_kind": "Copie Integrale",
107
        "document_kind_raw": "CPI",
108
        "event_date_end": "",
109
        "event_date_start": "2012-07-14",
110
        "event_district": "Val-de-Marne",
111
        "reason": "They are just messy"
112
    },
113
    "id": "demande-d-un-acte-de-naissance/4",
114
    "last_update_time": "2016-10-19T14:00:19Z",
115
    "receipt_time": "2016-10-19T14:00:19Z",
116
    "roles": {
117
        "_receiver": [
118
            {
119
                "allows_backoffice_access": true,
120
                "details": "",
121
                "emails": [],
122
                "emails_to_members": false,
123
                "id": "22",
124
                "name": "Etat civil Acte",
125
                "slug": "etat-civil-acte",
126
                "text": "Etat civil Acte"
127
            }
128
        ],
129
        "actions": [
130
            {
131
                "allows_backoffice_access": true,
132
                "details": "",
133
                "emails": [],
134
                "emails_to_members": false,
135
                "id": "3",
136
                "name": "agent",
137
                "slug": "agent",
138
                "text": "agent"
139
            }
140
        ],
141
        "concerned": [
142
            {
143
                "allows_backoffice_access": true,
144
                "details": "",
145
                "emails": [],
146
                "emails_to_members": false,
147
                "id": "3",
148
                "name": "agent",
149
                "slug": "agent",
150
                "text": "agent"
151
            },
152
            {
153
                "allows_backoffice_access": true,
154
                "details": "",
155
                "emails": [],
156
                "emails_to_members": false,
157
                "id": "22",
158
                "name": "Etat civil Acte",
159
                "slug": "etat-civil-acte",
160
                "text": "Etat civil Acte"
161
            }
162
        ]
163
    },
164
    "submission": {
165
        "backoffice": false,
166
        "channel": "web"
167
    },
168
    "url": "http://wcs.debian.local/demande-d-un-acte-de-naissance/4/",
169
    "user": {
170
        "email": "chelsea@whatever.com",
171
        "id": "2",
172
        "name": "chelsea"
173
    },
174
    "workflow": {
175
        "fields": {
176
            "aec_type": "Acte de naissance",
177
            "aec_type_raw": "NAISSANCE"
178
        },
179
        "status": {
180
            "id": "2",
181
            "name": "new"
182
        }
183
    }
184
}
tests/test_cityweb.py
1
# -*- coding: utf-8 -*-
2
# Passerelle - uniform access to data and services
3
# Copyright (C) 2017  Entr'ouvert
4
#
5
# This program is free software: you can redistribute it and/or modify it
6
# under the terms of the GNU Affero General Public License as published
7
# by the Free Software Foundation, either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU Affero General Public License for more details.
14
#
15
# You should have received a.deepcopy of the GNU Affero General Public License
16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
from __future__ import unicode_literals
18

  
19
import os
20
import json
21
import shutil
22

  
23
import pytest
24
import mock
25
from lxml import etree as letree
26

  
27
import utils
28

  
29
from passerelle.apps.cityweb.models import CityWeb
30

  
31

  
32
def get_test_base_dir(name):
33
    return os.path.join(os.path.dirname(__file__), 'data', name)
34

  
35

  
36
def get_file_from_test_base_dir(filename):
37
    path = os.path.join(get_test_base_dir('cityweb'), filename)
38
    with open(path, 'rb') as fd:
39
        return fd.read()
40

  
41

  
42
@pytest.fixture
43
def setup(db):
44
    return utils.setup_access_rights(CityWeb.objects.create(slug='test'))
45

  
46

  
47
PAYLOAD = [
48
    {
49
        'naissance': json.loads(get_file_from_test_base_dir('formdata_nais.json'))
50
    },
51
    {
52
        'mariage': json.loads(get_file_from_test_base_dir('formdata_mar.json'))
53
    },
54
    {
55
        'deces': json.loads(get_file_from_test_base_dir('formdata_dec.json'))
56
    }
57
]
58

  
59

  
60
@pytest.fixture(params=PAYLOAD)
61
def payload(request):
62
    return request.param
63

  
64

  
65
def assert_xml_doc(doc):
66
    schema = letree.XMLSchema(
67
        letree.parse(os.path.join(get_test_base_dir('cityweb'), 'cityweb.xsd')))
68
    schema.assertValid(doc)
69

  
70

  
71
@mock.patch('passerelle.apps.cityweb.models.default_storage.path', get_test_base_dir)
72
def test_demand_creation(app, setup, payload):
73
    url = '/cityweb/test/create/'
74
    if 'naissance' in payload:
75
        response = app.post_json(url, params=payload['naissance'])
76
        assert response.json['data']['demand_id'] == '15-4-NAI'
77
        doc = letree.parse(
78
            os.path.join(get_test_base_dir('cityweb'), 'test', '15-4-NAI', '15-4-NAI.xml'))
79
        assert_xml_doc(doc)
80

  
81
    elif 'mariage' in payload:
82
        response = app.post_json(url, params=payload['mariage'])
83
        assert response.json['data']['demand_id'] == '16-1-MAR'
84
        doc = letree.parse(
85
            os.path.join(get_test_base_dir('cityweb'), 'test', '16-1-MAR', '16-1-MAR.xml'))
86
        assert_xml_doc(doc)
87
    else:
88
        response = app.post_json(url, params=payload['deces'])
89
        assert response.json['data']['demand_id'] == '17-1-DEC'
90
        doc = letree.parse(
91
            os.path.join(get_test_base_dir('cityweb'), 'test', '17-1-DEC', '17-1-DEC.xml'))
92
        assert_xml_doc(doc)
93

  
94

  
95
def test_datasource_titles(app, setup):
96
    response = app.get('/cityweb/test/titles/')
97
    data = response.json['data']
98
    assert len(data) == 3
99
    for datum in data:
100
        if datum['id'] == 'M':
101
            assert datum['text'] == 'Monsieur'
102
        elif datum['id'] == 'Mme':
103
            assert datum['text'] == 'Madame'
104
        else:
105
            assert datum['id'] == 'Mlle'
106
            assert datum['text'] == 'Mademoiselle'
107

  
108

  
109
def test_datasource_genders(app, setup):
110
    response = app.get('/cityweb/test/genders/')
111
    data = response.json['data']
112
    assert len(data) == 3
113
    for datum in data:
114
        if datum['id'] == 'M':
115
            assert datum['text']
116
        elif datum['id'] == 'F':
117
            assert datum['text'] == 'Femme'
118
        else:
119
            assert datum['id'] == 'NA'
120
            assert datum['text'] == 'Autre'
121

  
122

  
123
def test_datasource_concerned(app, setup):
124
    response = app.get('/cityweb/test/concerned/')
125
    data = response.json['data']
126
    assert len(data) == 2
127
    for datum in data:
128
        if datum['id'] == 'reconnu':
129
            assert datum['text'] == 'Reconnu'
130
        else:
131
            assert datum['id'] == 'auteur'
132
            assert datum['text'] == 'Auteur'
133

  
134

  
135
def test_datasource_channels(app, setup):
136
    response = app.get('/cityweb/test/channels/')
137
    data = response.json['data']
138
    assert len(data) == 3
139
    for datum in data:
140
        if datum['id'] == 'internet':
141
            assert datum['text'] == 'Internet'
142
        elif datum['id'] == 'guichet':
143
            assert datum['text'] == 'Guichet'
144
        else:
145
            assert datum['id'] == 'courrier'
146
            assert datum['text'] == 'Courrier'
147

  
148

  
149
def test_datasource_documents_kind(app, setup):
150
    response = app.get('/cityweb/test/documents-kind/')
151
    data = response.json['data']
152
    assert len(data) == 4
153
    for datum in data:
154
        if datum['id'] == 'CPI':
155
            assert datum['text'] == 'Copie intégrale'
156
        elif datum['id'] == 'EXTAF':
157
            assert datum['text'] == 'Extrait avec filiation'
158
        elif datum['id'] == 'EXTSF':
159
            assert datum['text'] == 'Extrait sans filiation'
160
        else:
161
            datum['id'] == 'EXTPL'
162
            datum['text'] == 'Extrait plurilingue'
163

  
164
    params = {'without': 'EXTAF,EXTSF,EXTPL'}
165
    response = app.get('/cityweb/test/documents-kind/', params=params)
166
    data = response.json['data']
167
    assert len(data) == 1
168
    assert data[0]['id'] == 'CPI'
169
    assert data[0]['text'] == 'Copie intégrale'
170

  
171

  
172
def test_datasource_events_kind(app, setup):
173
    response = app.get('/cityweb/test/events-kind/')
174
    data = response.json['data']
175
    assert len(data) == 4
176
    for datum in data:
177
        if datum['id'] == 'NAI':
178
            assert datum['text'] == 'Naissance'
179
        elif datum['id'] == 'MAR':
180
            assert datum['text'] == 'Mariage'
181
        elif datum['id'] == 'REC':
182
            assert datum['text'] == 'Reconnaissance'
183
        else:
184
            assert datum['id'] == 'DEC'
185
            assert datum['text'] == 'Décès'
186

  
187

  
188
def teardown_module(module):
189
    # remove test/inputs from fs
190
    shutil.rmtree(os.path.join(get_test_base_dir('cityweb'), 'test'), ignore_errors=True)
0
-