From 13c1b0619300e87142e0c4bfe749b0e6670041ce Mon Sep 17 00:00:00 2001 From: Josue Kouka Date: Tue, 23 May 2017 00:40:18 +0200 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 diff --git a/passerelle/apps/cityweb/__init__.py b/passerelle/apps/cityweb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/passerelle/apps/cityweb/cityweb.py b/passerelle/apps/cityweb/cityweb.py new file mode 100644 index 0000000..e9c22e2 --- /dev/null +++ b/passerelle/apps/cityweb/cityweb.py @@ -0,0 +1,96 @@ +# Copyright (C) 2017 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import os +from collections import OrderedDict + +from dateutil.parser import parse as dateutil_parse + +from django.core.files.storage import default_storage +from django.core.files.base import ContentFile + +from passerelle.utils.jsonresponse import APIError +from passerelle.contrib.mdel.utils import ElementFactory, json_to_xml, zipdir, etree +from .mapping import MAPPING + + +ALLOWED_VALUES = { + '_title_raw': ('M', 'Mme', 'Mlle'), # {applicant_, concerned_, partner_}{father, mother} + '_gender_raw': ('M', 'F', 'NA'), # {applicant_, concerned_, partner_}{father, mother} + 'document_kind_raw': ('CPI', 'EXTAF', 'EXTSF', 'EXTPL'), + 'concerned_kind_raw': ('reconnu', 'auteur'), + 'event_kind_raw': ('NAI', 'MAR', 'REC', 'DEC'), + 'canal_raw': ('internet', 'guichet', 'courrier') +} + + +def is_value_allowed(key, value, allowed_values): + if value not in allowed_values: + raise APIError('Invalid value for %s: %s not in %s' + % (key, value, allowed_values)) + + +class CivilStatusApplication(object): + root_element = 'demandeEtatCivil' + mapping = MAPPING + namespace = 'http://tempuri.org/XMLSchema.xsd' + + def __init__(self, demand_id, data): + self.application_id = demand_id + self.data = self.validate(data) + + def validate(self, data): + data['application_id'] = self.application_id + data['application_date'] = data['receipt_time'] + applicant_is_concerned = data.pop('applicant_is_concerned', False) + if applicant_is_concerned: + data['concerned_kind'] = 'auteur' + + for key in data.keys(): + # set all dates to ISO format + if '_date' in key and data.get(key): + if key == 'application_date': + continue + data[key] = dateutil_parse(data[key]).date().isoformat() + # check value validity for key with value constraint + for pattern, allowed_values in ALLOWED_VALUES.items(): + if key.endswith(pattern) and data.get(key): + is_value_allowed(pattern, data[key], allowed_values) + # if the applicant is the concerned person, then all + # applicant vars values are copied + if key.startswith('applicant_') and applicant_is_concerned: + if key == 'applicant_kind': + continue + data[key.replace('applicant', 'concerned')] = data[key] + return data + + @property + def xml(self): + elements = OrderedDict() + for var, elt in self.mapping.items(): + if self.data.get(var): + elements[elt] = self.data[var] + + etree.register_namespace('xs', 'http://tempuri.org/XMLSchema.xsd') + root = ElementFactory(self.root_element, namespace=self.namespace) + for key, value in elements.items(): + path = key.split('_') + root.append(json_to_xml(path, value, root, namespace=self.namespace), allow_new=False) + return root + + def save(self, path): + filepath = os.path.join(path, self.application_id + '.xml') + default_storage.save(filepath, ContentFile(self.xml.to_pretty_xml())) + return zipdir(path) diff --git a/passerelle/apps/cityweb/mapping.py b/passerelle/apps/cityweb/mapping.py new file mode 100644 index 0000000..ab789ec --- /dev/null +++ b/passerelle/apps/cityweb/mapping.py @@ -0,0 +1,313 @@ +from collections import OrderedDict + + +MAPPING = OrderedDict(( + # + ("application_id", "identifiant"), + + # + # + ("applicant_kind", "demandeur_qualiteDemandeur"), + # + ("applicant_names_family", "demandeur_individu_noms_nomDeFamille"), + # + ("applicant_names_common", "demandeur_individu_noms_nomUsage"), + # + ("applicant_names_use", "demandeur_individu_noms_typeUsage"), + # + ("applicant_firstnames", "demandeur_individu_prenoms"), + # + ("applicant_title_raw", "demandeur_individu_genre"), + # + ("applicant_address_1", "demandeur_individu_adresse_ligneAdr1"), + # + ("applicant_address_2", "demandeur_individu_adresse_ligneAdr2"), + # + ("applicant_address_zipcode", "demandeur_individu_adresse_codePostal"), + # + ("applicant_address_city", "demandeur_individu_adresse_lieu_ville"), + # + ("applicant_address_district", "demandeur_individu_adresse_lieu_province"), + # + ("applicant_address_country", "demandeur_individu_adresse_lieu_pays"), + # + ("applicant_address_mail", "demandeur_individu_adresse_mail"), + # + ("applicant_address_tel", "demandeur_individu_adresse_tel"), + # + ("applicant_gender_raw", "demandeur_individu_sexe"), + # + ("applicant_birth_date", "demandeur_individu_naissance_date"), + # + ("applicant_birth_city", "demandeur_individu_naissance_lieu_ville"), + # + ("applicant_birth_district", "demandeur_individu_naissance_lieu_province"), + # + ("applicant_birth_country", "demandeur_individu_naissance_lieu_pays"), + # + + # + ("document_kind_raw", "natureDocument"), + # + ("copies", "nbExemplaire"), + # + ("application_date", "dateDemande"), + + # + + + ############################# + # + ############################## + + # + ("concerned_names_family", "evenement_interesse_noms_nomDeFamille"), + # + ("concerned_names_common", "evenement_interesse_noms_nomUsage"), + # + ("concerned_names_use", "evenement_interesse_noms_typeUsage"), + # + ("concerned_firstnames", "evenement_interesse_prenoms"), + # + ("concerned_title_raw", "evenement_interesse_genre"), + # + ("concerned_address_1", "evenement_interesse_adresse_ligneAdr1"), + # + ("concerned_address_2", "evenement_interesse_adresse_ligneAdr2"), + # + ("concerned_address_zipcode", "evenement_interesse_adresse_codePostal"), + # + ("concerned_address_city", "evenement_interesse_adresse_lieu_ville"), + # + ("concerned_address_district", "evenement_interesse_adresse_lieu_province"), + # + ("concerned_address_country", "evenement_interesse_adresse_lieu_pays"), + # + ("concerned_address_mail", "evenement_interesse_adresse_mail"), + # + ("concerned_address_tel", "evenement_interesse_adresse_tel"), + # + ("concerned_gender_raw", "evenement_interesse_sexe"), + # + ("concerned_birth_date", "evenement_interesse_naissance_date"), + # + ("concerned_birth_city", "evenement_interesse_naissance_lieu_ville"), + # + ("concerned_birth_district", "evenement_interesse_naissance_lieu_province"), + # + ("concerned_birth_country", "evenement_interesse_naissance_lieu_pays"), + + # # + # ("concerned_father_names_family", "evenement_interesse_pere_noms_nomDeFamille"), + # # + # ("concerned_father_names_common", "evenement_interesse_pere_noms_nomUsage"), + # # + # ("concerned_father_names_use", "evenement_interesse_pere_noms_typeUsage"), + # # + # ("concerned_father_firstnames", "evenement_interesse_pere_prenoms"), + # # + # ("concerned_father_title_raw", "evenement_interesse_pere_genre"), + # # + # ("concerned_father_address_1", "evenement_interesse_pere_adresse_ligneAdr1"), + # # + # ("concerned_father_address_2", "evenement_interesse_pere_adresse_ligneAdr2"), + # # + # ("concerned_father_address_zipcode", "evenement_interesse_pere_adresse_codePostal"), + # # + # ("concerned_father_address_city", "evenement_interesse_pere_adresse_lieu_ville"), + # # + # ("concerned_father_address_district", "evenement_interesse_pere_adresse_lieu_province"), + # # + # ("concerned_father_address_country", "evenement_interesse_pere_adresse_lieu_pays"), + # # + # ("concerned_father_address_mail", "evenement_interesse_pere_adresse_mail"), + # # + # ("concerned_father_address_tel", "evenement_interesse_pere_adresse_tel"), + # # + # ("concerned_father_gender_raw", "evenement_interesse_pere_sexe"), + # # + # ("concerned_father_birth_date", "evenement_interesse_pere_naissance_date"), + # # + # ("concerned_father_birth_city", "evenement_interesse_pere_naissance_lieu_ville"), + # # + # ("concerned_father_birth_district", "evenement_interesse_pere_naissance_lieu_province"), + # # + # ("concerned_father_birth_country", "evenement_interesse_pere_naissance_lieu_pays"), + + # # + # ("concerned_mother_names_family", "evenement_interesse_mere_noms_nomDeFamille"), + # # + # ("concerned_mother_names_common", "evenement_interesse_mere_noms_nomUsage"), + # # + # ("concerned_mother_names_use", "evenement_interesse_mere_noms_typeUsage"), + # # + # ("concerned_mother_firstnames", "evenement_interesse_mere_prenoms"), + # # + # ("concerned_mother_title_raw", "evenement_interesse_mere_genre"), + # # + # ("concerned_mother_address_1", "evenement_interesse_mere_adresse_ligneAdr1"), + # # + # ("concerned_mother_address_2", "evenement_interesse_mere_adresse_ligneAdr2"), + # # + # ("concerned_mother_address_zipcode", "evenement_interesse_mere_adresse_codePostal"), + # # + # ("concerned_mother_address_city", "evenement_interesse_mere_adresse_lieu_ville"), + # # + # ("concerned_mother_address_district", "evenement_interesse_mere_adresse_lieu_province"), + # # + # ("concerned_mother_address_country", "evenement_interesse_mere_adresse_lieu_pays"), + # # + # ("concerned_mother_address_mail", "evenement_interesse_mere_adresse_mail"), + # # + # ("concerned_mother_address_tel", "evenement_interesse_mere_adresse_tel"), + # # + # ("concerned_mother_gender_raw", "evenement_interesse_mere_sexe"), + # # + # ("concerned_mother_birth_date", "evenement_interesse_mere_naissance_date"), + # # + # ("concerned_mother_birth_city", "evenement_interesse_mere_naissance_lieu_ville"), + # # + # ("concerned_mother_birth_district", "evenement_interesse_mere_naissance_lieu_province"), + # # + # ("concerned_mother_birth_country", "evenement_interesse_mere_naissance_lieu_pays"), + + + + ############################# + # + ############################## + # + # + ("partner_names_family", "evenement_conjoint_noms_nomDeFamille"), + # + ("partner_names_common", "evenement_conjoint_noms_nomUsage"), + # + ("partner_names_use", "evenement_conjoint_noms_typeUsage"), + # + ("partner_firstnames", "evenement_conjoint_prenoms"), + # + ("partner_title_raw", "evenement_conjoint_genre"), + # + ("partner_address_1", "evenement_conjoint_adresse_ligneAdr1"), + # + ("partner_address_2", "evenement_conjoint_adresse_ligneAdr2"), + # + ("partner_address_zipcode", "evenement_conjoint_adresse_codePostal"), + # + ("partner_address_city", "evenement_conjoint_adresse_lieu_ville"), + # + ("partner_address_district", "evenement_conjoint_adresse_lieu_province"), + # + ("partner_address_country", "evenement_conjoint_adresse_lieu_pays"), + # + ("partner_address_mail", "evenement_conjoint_adresse_mail"), + # + ("partner_address_tel", "evenement_conjoint_adresse_tel"), + # + ("partner_gender_raw", "evenement_conjoint_sexe"), + # + ("partner_birth_date", "evenement_conjoint_naissance_date"), + # + ("partner_birth_city", "evenement_conjoint_naissance_lieu_ville"), + # + ("partner_birth_district", "evenement_conjoint_naissance_lieu_province"), + # + ("partner_birth_country", "evenement_conjoint_naissance_lieu_pays"), + + # # + # ("partner_father_names_family", "evenement_conjoint_pere_noms_nomDeFamille"), + # # + # ("partner_father_names_common", "evenement_conjoint_pere_noms_nomUsage"), + # # + # ("partner_father_names_use", "evenement_conjoint_pere_noms_typeUsage"), + # # + # ("partner_father_firstnames", "evenement_conjoint_pere_prenoms"), + # # + # ("partner_father_title_raw", "evenement_conjoint_pere_genre"), + # # + # ("partner_father_address_1", "evenement_conjoint_pere_adresse_ligneAdr1"), + # # + # ("partner_father_address_2", "evenement_conjoint_pere_adresse_ligneAdr2"), + # # + # ("partner_father_address_zipcode", "evenement_conjoint_pere_adresse_codePostal"), + # # + # ("partner_father_address_city", "evenement_conjoint_pere_adresse_lieu_ville"), + # # + # ("partner_father_address_district", "evenement_conjoint_pere_adresse_lieu_province"), + # # + # ("partner_father_address_country", "evenement_conjoint_pere_adresse_lieu_pays"), + # # + # ("partner_father_address_mail", "evenement_conjoint_pere_adresse_mail"), + # # + # ("partner_father_address_tel", "evenement_conjoint_pere_adresse_tel"), + # # + # ("partner_father_gender_raw", "evenement_conjoint_pere_sexe"), + # # + # ("partner_father_birth_date", "evenement_conjoint_pere_naissance_date"), + # # + # ("partner_father_birth_city", "evenement_conjoint_pere_naissance_lieu_ville"), + # # + # ("partner_father_birth_district", "evenement_conjoint_pere_naissance_lieu_province"), + # # + # ("partner_father_birth_country", "evenement_conjoint_pere_naissance_lieu_pays"), + + # # + # ("partner_mother_names_family", "evenement_conjoint_mere_noms_nomDeFamille"), + # # + # ("partner_mother_names_common", "evenement_conjoint_mere_noms_nomUsage"), + # # + # ("partner_mother_names_use", "evenement_conjoint_mere_noms_typeUsage"), + # # + # ("partner_mother_firstnames", "evenement_conjoint_mere_prenoms"), + # # + # ("partner_mother_title_raw", "evenement_conjoint_mere_genre"), + # # + # ("partner_mother_address_1", "evenement_conjoint_mere_adresse_ligneAdr1"), + # # + # ("partner_mother_address_2", "evenement_conjoint_mere_adresse_ligneAdr2"), + # # + # ("partner_mother_address_zipcode", "evenement_conjoint_mere_adresse_codePostal"), + # # + # ("partner_mother_address_city", "evenement_conjoint_mere_adresse_lieu_ville"), + # # + # ("partner_mother_address_district", "evenement_conjoint_mere_adresse_lieu_province"), + # # + # ("partner_mother_address_country", "evenement_conjoint_mere_adresse_lieu_pays"), + # # + # ("partner_mother_address_mail", "evenement_conjoint_mere_adresse_mail"), + # # + # ("partner_mother_address_tel", "evenement_conjoint_mere_adresse_tel"), + # # + # ("partner_mother_gender_raw", "evenement_conjoint_mere_sexe"), + # # + # ("partner_mother_birth_date", "evenement_conjoint_mere_naissance_date"), + # # + # ("partner_mother_birth_city", "evenement_conjoint_mere_naissance_lieu_ville"), + # # + # ("partner_mother_birth_district", "evenement_conjoint_mere_naissance_lieu_province"), + # # + # ("partner_mother_birth_country", "evenement_conjoint_mere_naissance_lieu_pays"), + + # + ("event_kind_raw", "evenement_natureEvenement"), + # + ("concerned_kind", "evenement_typeInteresse"), + # + ("event_date_start", "evenement_dateEvenement_dateDebut"), + # + ("event_date_end", "evenement_dateEvenement_dateFin"), + # + ("event_city", "evenement_lieuEvenement_ville"), + # + ("event_district", "evenement_lieuEvenement_province"), + # + ("event_country", "evenement_lieuEvenement_pays"), + # + + # + ("reason", "motif"), + # + ("canal", "origine"), + # + ("comment", "commentaire"), +)) diff --git a/passerelle/apps/cityweb/models.py b/passerelle/apps/cityweb/models.py new file mode 100644 index 0000000..a8fad55 --- /dev/null +++ b/passerelle/apps/cityweb/models.py @@ -0,0 +1,146 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2017 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import os +import json + +from dateutil.parser import parse as dateutil_parse + +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.core.files.storage import default_storage + +from passerelle.base.models import BaseResource +from passerelle.utils.api import endpoint +from passerelle.utils.jsonresponse import APIError +from passerelle.contrib.mdel.utils import flatten_payload + +from .cityweb import CivilStatusApplication + + +EVENTS_KIND = [ + {"id": "NAI", "text": "Naissance"}, + {"id": "MAR", "text": "Mariage"}, + {"id": "REC", "text": "Reconnaissance"}, + {"id": "DEC", "text": "Décès"} +] + +GENDERS = [ + {"id": "M", "text": "Homme"}, + {"id": "F", "text": "Femme"}, + {"id": "NA", "text": "Autre"} +] + +TITLES = [ + {"id": "M", "text": "Monsieur"}, + {"id": "Mme", "text": "Madame"}, + {"id": "Mlle", "text": "Mademoiselle"} +] + +DOCUMENTS_KIND = [ + {"id": "CPI", "text": "Copie intégrale"}, + {"id": "EXTAF", "text": "Extrait avec filiation"}, + {"id": "EXTSF", "text": "Extrait sans filiation"}, + {"id": "EXTPL", "text": "Extrait plurilingue"} +] + +CONCERNED = [ + {"id": "reconnu", "text": "Reconnu"}, + {"id": "auteur", "text": "Auteur"} +] + +CHANNELS = [ + {"id": "internet", "text": "Internet"}, + {"id": "guichet", "text": "Guichet"}, + {"id": "courrier", "text": "Courrier"} +] + + +class CityWeb(BaseResource): + category = _('Business Process Connectors') + + class Meta: + verbose_name = "CityWeb - Demande d'acte d'état civil" + + @classmethod + def get_verbose_name(cls): + return cls._meta.verbose_name + + @endpoint(serializer_type='json-api', perm='can_access', methods=['post']) + def create(self, request, *args, **kwargs): + formdata = json.loads(request.body) + formdata.update(flatten_payload(formdata.pop('fields'), formdata.pop('extra'))) + # check mandatory keys + for key in ('display_id', 'receipt_time', 'event_kind_raw'): + if key not in formdata: + raise APIError('<%s> is required' % key) + + attrs = { + 'demand_id': '%s-%s' % (formdata['display_id'], formdata['event_kind_raw']), + 'kind': formdata['event_kind_raw'], 'resource': self, + 'received_at': dateutil_parse(formdata['receipt_time'])} + + demand, created = Demand.objects.get_or_create(**attrs) + result = demand.create(formdata) + return {'demand_id': result} + + @endpoint(serializer_type='json-api', perm='can_access') + def titles(self, request): + return TITLES + + @endpoint(serializer_type='json-api', perm='can_access') + def genders(self, request): + return GENDERS + + @endpoint(serializer_type='json-api', perm='can_access') + def concerned(self, request): + return CONCERNED + + @endpoint(serializer_type='json-api', perm='can_access') + def channels(self, request): + return CHANNELS + + @endpoint(name='events-kind', serializer_type='json-api', perm='can_access') + def events_kind(self, request, without=''): + return [item for item in EVENTS_KIND + if item.get('id') not in without.split(',')] + + @endpoint(name='documents-kind', serializer_type='json-api', perm='can_access') + def documents_kind(self, request, without=''): + return [item for item in DOCUMENTS_KIND + if item.get('id') not in without.split(',')] + + +class Demand(models.Model): + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + received_at = models.DateTimeField() + resource = models.ForeignKey(CityWeb) + demand_id = models.CharField(max_length=32, primary_key=True) + kind = models.CharField(max_length=32) + + def __unicode__(self): + return '%s - %s - %s' % (self.resource.slug, self.demand_id) + + @property + def filepath(self): + return os.path.join( + default_storage.path('cityweb'), self.resource.slug, self.demand_id) + + def create(self, data): + application = CivilStatusApplication(self.demand_id, data) + application.save(self.filepath) + return self.demand_id diff --git a/passerelle/apps/cityweb/templates/cityweb/cityweb_detail.html b/passerelle/apps/cityweb/templates/cityweb/cityweb_detail.html new file mode 100644 index 0000000..53e5007 --- /dev/null +++ b/passerelle/apps/cityweb/templates/cityweb/cityweb_detail.html @@ -0,0 +1,192 @@ +{% extends "passerelle/manage/service_view.html" %} +{% load i18n passerelle %} + +{% block endpoints %} +
    +
  • +

    {%trans 'Create Demand'%}

    + {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="create" as create %} +

    POST {{create}}

    +
      +
    • application_id / display_id
    • +
    • application_application_date / receipt_time
    • + +
    • applicant_kind ('avocat', 'notaire', 'père', 'mère')
    • +
    • applicant_names_family
    • +
    • applicant_names_common
    • +
    • applicant_names_use (maiden name, widow name)
    • +
    • applicant_firstnames
    • +
    • applicant_title ('M', 'Mme', 'Mlle')
    • +
    • applicant_gender ('M', 'F', 'NA')
    • +
    • applicant_address_1
    • +
    • applicant_address_2
    • +
    • applicant_address_zipcode
    • +
    • applicant_address_city
    • +
    • applicant_address_district
    • +
    • applicant_address_country
    • +
    • applicant_address_mail
    • +
    • applicant_address_tel
    • +
    • applicant_birth_date
    • +
    • applicant_birth_city
    • +
    • applicant_birth_district
    • +
    • applicant_birth_country
    • +
    • applicant_kind
    • + +
    • document_kind ('CPI', 'EXTAF', 'EXTSF', 'EXTPL')
    • +
    • copies
    • + +
    • applicant_is_concerned (true, false)
    • +
    • concerned_kind ('reconnu', 'auteur')
    • +
    • concerned_names_family
    • +
    • concerned_names_common
    • +
    • concerned_names_use (maiden name, widow)
    • +
    • concerned_firstnames
    • +
    • concerned_title
    • +
    • concerned_gender
    • +
    • concerned_address_1
    • +
    • concerned_address_2
    • +
    • concerned_address_zipcode
    • +
    • concerned_address_city
    • +
    • concerned_address_district
    • +
    • concerned_address_country
    • +
    • concerned_address_mail
    • +
    • concerned_address_tel
    • +
    • concerned_birth_date
    • +
    • concerned_birth_city
    • +
    • concerned_birth_district
    • +
    • concerned_birth_country
    • + +
    • concerned_father_names_family
    • +
    • concerned_father_names_common
    • +
    • concerned_father_names_use (maiden name, widow)
    • +
    • concerned_father_firstnames
    • +
    • concerned_father_title
    • +
    • concerned_father_gender
    • +
    • concerned_father_address_1
    • +
    • concerned_father_address_2
    • +
    • concerned_father_address_zipcode
    • +
    • concerned_father_address_city
    • +
    • concerned_father_address_district
    • +
    • concerned_father_address_country
    • +
    • concerned_father_address_mail
    • +
    • concerned_father_address_tel
    • +
    • concerned_father_birth_date
    • +
    • concerned_father_birth_city
    • +
    • concerned_father_birth_district
    • +
    • concerned_father_birth_country
    • + +
    • concerned_mother_names_family
    • +
    • concerned_mother_names_common
    • +
    • concerned_mother_names_use (maiden name, widow)
    • +
    • concerned_mother_firstnames
    • +
    • concerned_mother_title
    • +
    • concerned_mother_gender
    • +
    • concerned_mother_address_1
    • +
    • concerned_mother_address_2
    • +
    • concerned_mother_address_zipcode
    • +
    • concerned_mother_address_city
    • +
    • concerned_mother_address_district
    • +
    • concerned_mother_address_country
    • +
    • concerned_mother_address_mail
    • +
    • concerned_mother_address_tel
    • +
    • concerned_mother_birth_date
    • +
    • concerned_mother_birth_city
    • +
    • concerned_mother_birth_district
    • +
    • concerned_mother_birth_country
    • + +
    • partner_names_family
    • +
    • partner_names_common
    • +
    • partner_names_use (maiden name, widow)
    • +
    • partner_firstnames
    • +
    • partner_title
    • +
    • partner_gender
    • +
    • partner_address_1
    • +
    • partner_address_2
    • +
    • partner_address_zipcode
    • +
    • partner_address_city
    • +
    • partner_address_district
    • +
    • partner_address_country
    • +
    • partner_address_mail
    • +
    • partner_address_tel
    • +
    • partner_birth_date
    • +
    • partner_birth_city
    • +
    • partner_birth_district
    • +
    • partner_birth_country
    • + +
    • partner_father_kind
    • +
    • partner_father_names_family
    • +
    • partner_father_names_common
    • +
    • partner_father_names_use (maiden name, widow)
    • +
    • partner_father_firstnames
    • +
    • partner_father_title
    • +
    • partner_father_gender
    • +
    • partner_father_address_1
    • +
    • partner_father_address_2
    • +
    • partner_father_address_zipcode
    • +
    • partner_father_address_city
    • +
    • partner_father_address_district
    • +
    • partner_father_address_country
    • +
    • partner_father_address_mail
    • +
    • partner_father_address_tel
    • +
    • partner_father_birth_date
    • +
    • partner_father_birth_city
    • +
    • partner_father_birth_district
    • +
    • partner_father_birth_country
    • + +
    • partner_mother_kind
    • +
    • partner_mother_names_family
    • +
    • partner_mother_names_common
    • +
    • partner_mother_names_use (maiden name, widow)
    • +
    • partner_mother_firstnames
    • +
    • partner_mother_title
    • +
    • partner_mother_gender
    • +
    • partner_mother_address_1
    • +
    • partner_mother_address_2
    • +
    • partner_mother_address_zipcode
    • +
    • partner_mother_address_city
    • +
    • partner_mother_address_district
    • +
    • partner_mother_address_country
    • +
    • partner_mother_address_mail
    • +
    • partner_mother_address_tel
    • +
    • partner_mother_birth_date
    • +
    • partner_mother_birth_city
    • +
    • partner_mother_birth_district
    • +
    • partner_mother_birth_country
    • + +
    • event_kind ('NAI', 'DEC', 'MAR', 'REC')
    • + +
    • event_date_start
    • +
    • event_date_end
    • + +
    • event_city
    • +
    • event_district
    • +
    • event_country
    • +
    • reason
    • +
    • canal ('internet', 'guichet', 'courrier')
    • +
    • comment
    • +
    +
  • +
  • +

    {%trans 'Data Sources'%}

    + {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="titles" as get_titles %} +

    GET {{get_titles}}

    + {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="genders" as get_genders %} +

    GET {{get_genders}}

    + {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="concerned" as get_concerned %} +

    GET {{get_concerned}}

    + {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="channels" as get_channels %} +

    GET {{get_channels}}

    + {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="events-kind" as get_events_kind %} +

    GET {{get_events_kind}}?without=DEC,REC

    + {% url "generic-endpoint" connector="cityweb" slug=object.slug endpoint="documents-kind" as get_events_kind %} +

    GET {{get_documents_kind}}?without=EXTPL

    +
  • +
+{% endblock %} + +{% block security %} +

+ {% trans 'Access is limited to the following API users:' %} +

+{% access_rights_table resource=object permission='can_access' %} +{% endblock %} diff --git a/passerelle/settings.py b/passerelle/settings.py index 16a8c34..f03d004 100644 --- a/passerelle/settings.py +++ b/passerelle/settings.py @@ -113,6 +113,7 @@ INSTALLED_APPS = ( 'passerelle.apps.opengis', 'passerelle.apps.airquality', 'passerelle.apps.okina', + 'passerelle.apps.cityweb', # backoffice templates and static 'gadjo', ) diff --git a/tests/data/cityweb/cityweb.xsd b/tests/data/cityweb/cityweb.xsd new file mode 100644 index 0000000..be64220 --- /dev/null +++ b/tests/data/cityweb/cityweb.xsd @@ -0,0 +1,181 @@ + + + + + + Root element + + + + + + + utile si différent de l'interessé + + + + + copie intégrale, extrait avec ou sans filiation, plurilingue + + + + + + + + + origine de la demande pour l'état civil : courrier, guichet ou internet + + + + + champ commentaire + + + + + + + + + Naissance, mariage, décès, reconnaissance + + + + + + + + + + + + + + + + + + + + + + + Informations sur le demandeur + + + + + avocat, notaire, père, mère... + + + + + + + + permet de gérer le sexe indeterminé + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Seulement pour les mariages + + + + + naissance, mariage, décès, reconnaissance + + + + + necessaire pour les reconnaissances seulement, l'interessé pouvant etre le parent ou le reconnu, il faut donc préciser. + + + + + + + + + + + + + précission sur le nom d'usage: nom d'épouse, veuve, d'usage... + + + + + + + + + + + + + + + + + + + + + + + + + + Permet de gérer les dates incomplètes + + + + diff --git a/tests/data/cityweb/formdata_dec.json b/tests/data/cityweb/formdata_dec.json new file mode 100644 index 0000000..57996d7 --- /dev/null +++ b/tests/data/cityweb/formdata_dec.json @@ -0,0 +1,183 @@ +{ + "criticality_level": 0, + "display_id": "17-1", + "display_name": "Demande d'un acte de d\u00e9c\u00e8s #17-1", + "evolution": [ + { + "status": "2", + "time": "2016-10-20T14:41:20Z", + "who": { + "email": "chelsea@whatever.com", + "id": "2", + "name": "chelsea" + } + } + ], + "extra": { + "code_insee": "54395", + "code_postal": "54000", + "event_city": "Nantes", + "event_country": "France", + "event_kind": "Deces", + "event_kind_raw": "DEC" + }, + "fields": { + "applicant_address_1": "37 Rue du Cheval Blanc", + "applicant_address_2": "", + "applicant_address_city": "Nancy", + "applicant_address_country": "France", + "applicant_address_district": "Meurthe-et-Moselle", + "applicant_address_mail": "chelsea@whatever.com", + "applicant_address_tel": "+33 6 55 44 22 11", + "applicant_address_zipcode": "54000", + "applicant_birth_city": "Nantes", + "applicant_birth_country": "France", + "applicant_birth_date": "11/07/1989", + "applicant_birth_district": "Loire-Atlantique", + "applicant_firstnames": "Kim Chelsea", + "applicant_gender": "Femelle", + "applicant_gender_raw": "F", + "applicant_kind": "personne concern\u00e9", + "applicant_names_common": "Whatever", + "applicant_names_family": "Whatever", + "applicant_names_use": "nom d'epouse", + "applicant_title": "Madame", + "applicant_title_raw": "Mme", + "canal": "internet", + "concerned_address_1": "", + "concerned_address_2": "", + "concerned_address_city": "", + "concerned_address_country": "", + "concerned_address_district": "", + "concerned_address_mail": "", + "concerned_address_tel": "", + "concerned_address_zipcode": "", + "concerned_birth_city": "Harare", + "concerned_birth_country": "Zimbabwe", + "concerned_birth_date": "1980-02-29", + "concerned_birth_district": "", + "concerned_father_address_1": "21 Bvd Henri Orion", + "concerned_father_address_2": "Batiment A, Apt 18", + "concerned_father_address_city": "Nantes", + "concerned_father_address_country": "France", + "concerned_father_address_district": "Loite-Atlantique", + "concerned_father_address_mail": "", + "concerned_father_address_tel": "", + "concerned_father_address_zipcode": "44000", + "concerned_father_birth_city": "Orvault", + "concerned_father_birth_country": "France", + "concerned_father_birth_date": "11-04-1955", + "concerned_father_birth_district": "Loire-Atlantique", + "concerned_father_firstnames": "John Oliver", + "concerned_father_gender": "Male", + "concerned_father_gender_raw": "M", + "concerned_father_names_common": "Smith", + "concerned_father_names_family": "Smith", + "concerned_father_names_use": "Smith", + "concerned_father_title": "Monsieur", + "concerned_father_title_raw": "M", + "concerned_firstnames": "Kevin", + "concerned_gender_raw": "M", + "concerned_mother_address_1": "21 Bvd Henri Orion", + "concerned_mother_address_2": "Batiment A, Apt 18", + "concerned_mother_address_city": "Nantes", + "concerned_mother_address_country": "France", + "concerned_mother_address_district": "Loite-Atlantique", + "concerned_mother_address_mail": "kim@gmail.com", + "concerned_mother_address_tel": "", + "concerned_mother_address_zipcode": "44000", + "concerned_mother_birth_city": "Seoul", + "concerned_mother_birth_country": "South Korea", + "concerned_mother_birth_date": "10-05-1960", + "concerned_mother_birth_district": "", + "concerned_mother_firstnames": "Kim", + "concerned_mother_gender": "", + "concerned_mother_kind": "", + "concerned_mother_names_common": "Smith", + "concerned_mother_names_family": "Smith", + "concerned_mother_names_use": "nom d'\u00e9pouse", + "concerned_mother_title": "Mme", + "concerned_names_common": "Whatever", + "concerned_names_family": "Whatever", + "concerned_names_use": "", + "concerned_title_raw": "M", + "copies": "1", + "document_kind": "Copie Integrale", + "document_kind_raw": "CPI", + "event_date_end": "", + "event_date_start": "2012-07-14", + "event_district": "Val-de-Marne", + "reason": "They are just messy" + }, + "id": "demande-d-un-acte-de-deces/1", + "last_update_time": "2016-10-20T14:41:20Z", + "receipt_time": "2016-10-20T14:41:20Z", + "roles": { + "_receiver": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "22", + "name": "Etat civil Acte", + "slug": "etat-civil-acte", + "text": "Etat civil Acte" + } + ], + "actions": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "3", + "name": "agent", + "slug": "agent", + "text": "agent" + } + ], + "concerned": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "3", + "name": "agent", + "slug": "agent", + "text": "agent" + }, + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "22", + "name": "Etat civil Acte", + "slug": "etat-civil-acte", + "text": "Etat civil Acte" + } + ] + }, + "submission": { + "backoffice": false, + "channel": "web" + }, + "url": "http://wcs.debian.local/demande-d-un-acte-de-deces/1/", + "user": { + "email": "chelsea@whatever.com", + "id": "2", + "name": "chelsea" + }, + "workflow": { + "fields": { + "aec_type": null, + "aec_type_raw": null + }, + "status": { + "id": "2", + "name": "new" + } + } +} diff --git a/tests/data/cityweb/formdata_mar.json b/tests/data/cityweb/formdata_mar.json new file mode 100644 index 0000000..7e23e42 --- /dev/null +++ b/tests/data/cityweb/formdata_mar.json @@ -0,0 +1,242 @@ +{ + "criticality_level": 0, + "display_id": "16-1", + "display_name": "Demande d'un acte de mariage #16-1", + "evolution": [ + { + "status": "2", + "time": "2016-10-20T15:17:05Z", + "who": { + "email": "chelsea@whatever.com", + "id": "2", + "name": "chelsea" + } + } + ], + "extra": { + "code_insee": "54395", + "code_postal": "54000", + "event_city": "Nantes", + "event_country": "France", + "event_kind": "Mariage", + "event_kind_raw": "MAR" + }, + "fields": { + "applicant_is_concerned": true, + "applicant_address_1": "37 Rue du Cheval Blanc", + "applicant_address_2": "", + "applicant_address_city": "Nancy", + "applicant_address_country": "France", + "applicant_address_district": "Meurthe-et-Moselle", + "applicant_address_mail": "chelsea@whatever.com", + "applicant_address_tel": "+33 6 55 44 22 11", + "applicant_address_zipcode": "54000", + "applicant_birth_city": "Nantes", + "applicant_birth_country": "France", + "applicant_birth_date": "11/07/1989", + "applicant_birth_district": "Loire-Atlantique", + "applicant_firstnames": "Kim Chelsea", + "applicant_gender": "Femelle", + "applicant_gender_raw": "F", + "applicant_kind": "personne concern\u00e9", + "applicant_names_common": "Whatever", + "applicant_names_family": "Whatever", + "applicant_names_use": "nom d'epouse", + "applicant_title": "Madame", + "applicant_title_raw": "Mme", + "canal": "internet", + "concerned_address_1": "", + "concerned_address_2": "", + "concerned_address_city": "", + "concerned_address_country": "", + "concerned_address_district": "", + "concerned_address_mail": "", + "concerned_address_tel": "", + "concerned_address_zipcode": "", + "concerned_birth_city": "", + "concerned_birth_country": "", + "concerned_birth_date": "", + "concerned_birth_district": "", + "concerned_father_address_1": "21 Bvd Henri Orion", + "concerned_father_address_2": "Batiment A, Apt 18", + "concerned_father_address_city": "Nantes", + "concerned_father_address_country": "France", + "concerned_father_address_district": "Loite-Atlantique", + "concerned_father_address_mail": "", + "concerned_father_address_tel": "", + "concerned_father_address_zipcode": "44000", + "concerned_father_birth_city": "Orvault", + "concerned_father_birth_country": "France", + "concerned_father_birth_date": "11-04-1955", + "concerned_father_birth_district": "Loire-Atlantique", + "concerned_father_firstnames": "John Oliver", + "concerned_father_gender": "Male", + "concerned_father_gender_raw": "M", + "concerned_father_names_common": "Smith", + "concerned_father_names_family": "Smith", + "concerned_father_names_use": "Smith", + "concerned_father_title": "Monsieur", + "concerned_father_title_raw": "M", + "concerned_firstnames": "", + "concerned_gender": "", + "concerned_kind": "", + "concerned_mother_address_1": "21 Bvd Henri Orion", + "concerned_mother_address_2": "Batiment A, Apt 18", + "concerned_mother_address_city": "Nantes", + "concerned_mother_address_country": "France", + "concerned_mother_address_district": "Loite-Atlantique", + "concerned_mother_address_mail": "kim@gmail.com", + "concerned_mother_address_tel": "", + "concerned_mother_address_zipcode": "44000", + "concerned_mother_birth_city": "Seoul", + "concerned_mother_birth_country": "South Korea", + "concerned_mother_birth_date": "10-05-1960", + "concerned_mother_birth_district": "", + "concerned_mother_firstnames": "Kim", + "concerned_mother_gender": "", + "concerned_mother_kind": "", + "concerned_mother_names_common": "Smith", + "concerned_mother_names_family": "Smith", + "concerned_mother_names_use": "nom d'\u00e9pouse", + "concerned_mother_title": "Mme", + "concerned_names_common": "", + "concerned_names_family": "", + "concerned_names_use": "", + "concerned_title": "", + "copies": "2", + "document_kind": "Copie Integrale", + "document_kind_raw": "CPI", + "event_date_end": "", + "event_date_start": "2012-07-14", + "event_district": "Val-de-Marne", + "partner_address_1": "37 Rue du cheval Blanc", + "partner_address_2": "", + "partner_address_city": "Nancy", + "partner_address_country": "France", + "partner_address_district": "Meurthe-et-Moselle", + "partner_address_mail": "kevin@lost.com", + "partner_address_tel": "", + "partner_address_zipcode": "54000", + "partner_birth_city": "Paris", + "partner_birth_country": "France", + "partner_birth_date": "25-11-1985", + "partner_birth_district": "", + "partner_father_address_1": "West 12th Avenue", + "partner_father_address_2": "", + "partner_father_address_city": "Vancouver", + "partner_father_address_country": "Canada", + "partner_father_address_district": "British Columbia", + "partner_father_address_mail": "", + "partner_father_address_tel": "", + "partner_father_address_zipcode": "BC V5Y 1V4", + "partner_father_birth_city": "Vancouver", + "partner_father_birth_country": "Canada", + "partner_father_birth_date": "23-02-1957", + "partner_father_birth_district": "British Columbia", + "partner_father_firstnames": "Eric Eliot", + "partner_father_gender": "Male", + "partner_father_gender_raw": "M", + "partner_father_names_common": "Whatever", + "partner_father_names_family": "Whatever", + "partner_father_names_use": "", + "partner_father_title": "Monsieur", + "partner_father_title_raw": "M", + "partner_firstnames": "Kevin Johnny", + "partner_gender": "Male", + "partner_gender_raw": "M", + "partner_mother_address_1": "", + "partner_mother_address_2": "", + "partner_mother_address_city": "", + "partner_mother_address_country": "", + "partner_mother_address_district": "", + "partner_mother_address_mail": "", + "partner_mother_address_tel": "", + "partner_mother_address_zipcode": "", + "partner_mother_birth_city": "Sao Paolo", + "partner_mother_birth_country": "Brazil", + "partner_mother_birth_date": "11/06/1962", + "partner_mother_birth_district": "", + "partner_mother_firstnames": "Clara", + "partner_mother_gender": "F", + "partner_mother_names_common": "Whatever", + "partner_mother_names_family": "Da Silva", + "partner_mother_names_use": "nom d'epouse", + "partner_mother_title": "Madame", + "partner_mother_title_raw": "M", + "partner_names_common": "Whatever", + "partner_names_family": "Whatever", + "partner_title": "M", + "reason": "They are just messy" + }, + "id": "demande-d-un-acte-de-mariage/1", + "last_update_time": "2016-10-20T15:17:05Z", + "receipt_time": "2016-10-20T15:17:05Z", + "roles": { + "_receiver": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "22", + "name": "Etat civil Acte", + "slug": "etat-civil-acte", + "text": "Etat civil Acte" + } + ], + "actions": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "3", + "name": "agent", + "slug": "agent", + "text": "agent" + } + ], + "concerned": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "3", + "name": "agent", + "slug": "agent", + "text": "agent" + }, + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "22", + "name": "Etat civil Acte", + "slug": "etat-civil-acte", + "text": "Etat civil Acte" + } + ] + }, + "submission": { + "backoffice": false, + "channel": "web" + }, + "url": "http://wcs.debian.local/demande-d-un-acte-de-mariage/1/", + "user": { + "email": "chelsea@whatever.com", + "id": "2", + "name": "chelsea" + }, + "workflow": { + "fields": { + "aec_type": null, + "aec_type_raw": null + }, + "status": { + "id": "2", + "name": "new" + } + } +} diff --git a/tests/data/cityweb/formdata_nais.json b/tests/data/cityweb/formdata_nais.json new file mode 100644 index 0000000..3bb8e81 --- /dev/null +++ b/tests/data/cityweb/formdata_nais.json @@ -0,0 +1,184 @@ +{ + "criticality_level": 0, + "display_id": "15-4", + "display_name": "Demande d'un acte de naissance #15-4", + "evolution": [ + { + "status": "2", + "time": "2016-10-19T14:00:19Z", + "who": { + "email": "chelsea@whatever.com", + "id": "2", + "name": "chelsea" + } + } + ], + "extra": { + "code_insee": "54395", + "code_postal": "54000", + "event_city": "Nantes", + "event_country": "France", + "event_kind": "Naissance", + "event_kind_raw": "NAI" + }, + "fields": { + "applicant_address_1": "37 Rue du Cheval Blanc", + "applicant_address_2": "", + "applicant_address_city": "Nancy", + "applicant_address_country": "France", + "applicant_address_district": "Meurthe-et-Moselle", + "applicant_address_mail": "chelsea@whatever.com", + "applicant_address_tel": "+33 6 55 44 22 11", + "applicant_address_zipcode": "54000", + "applicant_birth_city": "Nantes", + "applicant_birth_country": "France", + "applicant_birth_date": "11/07/1989", + "applicant_birth_district": "Loire-Atlantique", + "applicant_firstnames": "Kim Chelsea", + "applicant_gender": "Femelle", + "applicant_gender_raw": "F", + "applicant_is_concerned": "true", + "applicant_kind": "personne concern\u00e9", + "applicant_names_common": "Whatever", + "applicant_names_family": "Whatever", + "applicant_names_use": "nom d'epouse", + "applicant_title": "Madame", + "applicant_title_raw": "Mme", + "canal": "internet", + "concerned_address_1": "", + "concerned_address_2": "", + "concerned_address_city": "", + "concerned_address_country": "", + "concerned_address_district": "", + "concerned_address_mail": "", + "concerned_address_tel": "", + "concerned_address_zipcode": "", + "concerned_birth_city": "Harare", + "concerned_birth_country": "Zimbabwe", + "concerned_birth_date": "1980-02-29", + "concerned_birth_district": "", + "concerned_father_address_1": "21 Bvd Henri Orion", + "concerned_father_address_2": "Batiment A, Apt 18", + "concerned_father_address_city": "Nantes", + "concerned_father_address_country": "France", + "concerned_father_address_district": "Loite-Atlantique", + "concerned_father_address_mail": "", + "concerned_father_address_tel": "", + "concerned_father_address_zipcode": "44000", + "concerned_father_birth_city": "Orvault", + "concerned_father_birth_country": "France", + "concerned_father_birth_date": "11-04-1955", + "concerned_father_birth_district": "Loire-Atlantique", + "concerned_father_firstnames": "John Oliver", + "concerned_father_gender": "Male", + "concerned_father_gender_raw": "M", + "concerned_father_names_common": "Smith", + "concerned_father_names_family": "Smith", + "concerned_father_names_use": "Smith", + "concerned_father_title": "Monsieur", + "concerned_father_title_raw": "M", + "concerned_firstnames": "Kevin", + "concerned_gender_raw": "M", + "concerned_mother_address_1": "21 Bvd Henri Orion", + "concerned_mother_address_2": "Batiment A, Apt 18", + "concerned_mother_address_city": "Nantes", + "concerned_mother_address_country": "France", + "concerned_mother_address_district": "Loite-Atlantique", + "concerned_mother_address_mail": "kim@gmail.com", + "concerned_mother_address_tel": "", + "concerned_mother_address_zipcode": "44000", + "concerned_mother_birth_city": "Seoul", + "concerned_mother_birth_country": "South Korea", + "concerned_mother_birth_date": "10-05-1960", + "concerned_mother_birth_district": "", + "concerned_mother_firstnames": "Kim", + "concerned_mother_gender": "", + "concerned_mother_kind": "", + "concerned_mother_names_common": "Smith", + "concerned_mother_names_family": "Smith", + "concerned_mother_names_use": "nom d'\u00e9pouse", + "concerned_mother_title": "Mme", + "concerned_names_common": "Whatever", + "concerned_names_family": "Whatever", + "concerned_names_use": "", + "concerned_title_raw": "M", + "copies": "1", + "document_kind": "Copie Integrale", + "document_kind_raw": "CPI", + "event_date_end": "", + "event_date_start": "2012-07-14", + "event_district": "Val-de-Marne", + "reason": "They are just messy" + }, + "id": "demande-d-un-acte-de-naissance/4", + "last_update_time": "2016-10-19T14:00:19Z", + "receipt_time": "2016-10-19T14:00:19Z", + "roles": { + "_receiver": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "22", + "name": "Etat civil Acte", + "slug": "etat-civil-acte", + "text": "Etat civil Acte" + } + ], + "actions": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "3", + "name": "agent", + "slug": "agent", + "text": "agent" + } + ], + "concerned": [ + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "3", + "name": "agent", + "slug": "agent", + "text": "agent" + }, + { + "allows_backoffice_access": true, + "details": "", + "emails": [], + "emails_to_members": false, + "id": "22", + "name": "Etat civil Acte", + "slug": "etat-civil-acte", + "text": "Etat civil Acte" + } + ] + }, + "submission": { + "backoffice": false, + "channel": "web" + }, + "url": "http://wcs.debian.local/demande-d-un-acte-de-naissance/4/", + "user": { + "email": "chelsea@whatever.com", + "id": "2", + "name": "chelsea" + }, + "workflow": { + "fields": { + "aec_type": "Acte de naissance", + "aec_type_raw": "NAISSANCE" + }, + "status": { + "id": "2", + "name": "new" + } + } +} diff --git a/tests/test_cityweb.py b/tests/test_cityweb.py new file mode 100644 index 0000000..46a45ed --- /dev/null +++ b/tests/test_cityweb.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Passerelle - uniform access to data and services +# Copyright (C) 2017 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a.deepcopy of the GNU Affero General Public License +# along with this program. If not, see . +from __future__ import unicode_literals + +import os +import json +import shutil + +import pytest +import mock +from lxml import etree as letree + +import utils + +from passerelle.apps.cityweb.models import CityWeb + + +def get_test_base_dir(name): + return os.path.join(os.path.dirname(__file__), 'data', name) + + +def get_file_from_test_base_dir(filename): + path = os.path.join(get_test_base_dir('cityweb'), filename) + with open(path, 'rb') as fd: + return fd.read() + + +@pytest.fixture +def setup(db): + return utils.setup_access_rights(CityWeb.objects.create(slug='test')) + + +PAYLOAD = [ + { + 'naissance': json.loads(get_file_from_test_base_dir('formdata_nais.json')) + }, + { + 'mariage': json.loads(get_file_from_test_base_dir('formdata_mar.json')) + }, + { + 'deces': json.loads(get_file_from_test_base_dir('formdata_dec.json')) + } +] + + +@pytest.fixture(params=PAYLOAD) +def payload(request): + return request.param + + +def assert_xml_doc(doc): + schema = letree.XMLSchema( + letree.parse(os.path.join(get_test_base_dir('cityweb'), 'cityweb.xsd'))) + schema.assertValid(doc) + + +@mock.patch('passerelle.apps.cityweb.models.default_storage.path', get_test_base_dir) +def test_demand_creation(app, setup, payload): + url = '/cityweb/test/create/' + if 'naissance' in payload: + response = app.post_json(url, params=payload['naissance']) + assert response.json['data']['demand_id'] == '15-4-NAI' + doc = letree.parse( + os.path.join(get_test_base_dir('cityweb'), 'test', '15-4-NAI', '15-4-NAI.xml')) + assert_xml_doc(doc) + + elif 'mariage' in payload: + response = app.post_json(url, params=payload['mariage']) + assert response.json['data']['demand_id'] == '16-1-MAR' + doc = letree.parse( + os.path.join(get_test_base_dir('cityweb'), 'test', '16-1-MAR', '16-1-MAR.xml')) + assert_xml_doc(doc) + else: + response = app.post_json(url, params=payload['deces']) + assert response.json['data']['demand_id'] == '17-1-DEC' + doc = letree.parse( + os.path.join(get_test_base_dir('cityweb'), 'test', '17-1-DEC', '17-1-DEC.xml')) + assert_xml_doc(doc) + + +def test_datasource_titles(app, setup): + response = app.get('/cityweb/test/titles/') + data = response.json['data'] + assert len(data) == 3 + for datum in data: + if datum['id'] == 'M': + assert datum['text'] == 'Monsieur' + elif datum['id'] == 'Mme': + assert datum['text'] == 'Madame' + else: + assert datum['id'] == 'Mlle' + assert datum['text'] == 'Mademoiselle' + + +def test_datasource_genders(app, setup): + response = app.get('/cityweb/test/genders/') + data = response.json['data'] + assert len(data) == 3 + for datum in data: + if datum['id'] == 'M': + assert datum['text'] + elif datum['id'] == 'F': + assert datum['text'] == 'Femme' + else: + assert datum['id'] == 'NA' + assert datum['text'] == 'Autre' + + +def test_datasource_concerned(app, setup): + response = app.get('/cityweb/test/concerned/') + data = response.json['data'] + assert len(data) == 2 + for datum in data: + if datum['id'] == 'reconnu': + assert datum['text'] == 'Reconnu' + else: + assert datum['id'] == 'auteur' + assert datum['text'] == 'Auteur' + + +def test_datasource_channels(app, setup): + response = app.get('/cityweb/test/channels/') + data = response.json['data'] + assert len(data) == 3 + for datum in data: + if datum['id'] == 'internet': + assert datum['text'] == 'Internet' + elif datum['id'] == 'guichet': + assert datum['text'] == 'Guichet' + else: + assert datum['id'] == 'courrier' + assert datum['text'] == 'Courrier' + + +def test_datasource_documents_kind(app, setup): + response = app.get('/cityweb/test/documents-kind/') + data = response.json['data'] + assert len(data) == 4 + for datum in data: + if datum['id'] == 'CPI': + assert datum['text'] == 'Copie intégrale' + elif datum['id'] == 'EXTAF': + assert datum['text'] == 'Extrait avec filiation' + elif datum['id'] == 'EXTSF': + assert datum['text'] == 'Extrait sans filiation' + else: + datum['id'] == 'EXTPL' + datum['text'] == 'Extrait plurilingue' + + params = {'without': 'EXTAF,EXTSF,EXTPL'} + response = app.get('/cityweb/test/documents-kind/', params=params) + data = response.json['data'] + assert len(data) == 1 + assert data[0]['id'] == 'CPI' + assert data[0]['text'] == 'Copie intégrale' + + +def test_datasource_events_kind(app, setup): + response = app.get('/cityweb/test/events-kind/') + data = response.json['data'] + assert len(data) == 4 + for datum in data: + if datum['id'] == 'NAI': + assert datum['text'] == 'Naissance' + elif datum['id'] == 'MAR': + assert datum['text'] == 'Mariage' + elif datum['id'] == 'REC': + assert datum['text'] == 'Reconnaissance' + else: + assert datum['id'] == 'DEC' + assert datum['text'] == 'Décès' + + +def teardown_module(module): + # remove test/inputs from fs + shutil.rmtree(os.path.join(get_test_base_dir('cityweb'), 'test'), ignore_errors=True) -- 2.11.0