From 1d2d3e485ab031aec8b105962bc70e5dc35f203b Mon Sep 17 00:00:00 2001 From: Thomas NOEL Date: Fri, 15 Oct 2021 12:18:06 +0000 Subject: [PATCH] sector: add a sector_name column in CSV, for readability (#57021) --- .../apps/sector/migrations/0001_initial.py | 8 ++- .../0002_sectorization_street_name.py | 18 +++++ passerelle/apps/sector/models.py | 19 +++++- tests/test_address.py | 10 +-- tests/test_import_export.py | 4 +- tests/test_sector.py | 67 +++++++++++-------- 6 files changed, 87 insertions(+), 39 deletions(-) create mode 100644 passerelle/apps/sector/migrations/0002_sectorization_street_name.py diff --git a/passerelle/apps/sector/migrations/0001_initial.py b/passerelle/apps/sector/migrations/0001_initial.py index 63ee4065..f2750fff 100644 --- a/passerelle/apps/sector/migrations/0001_initial.py +++ b/passerelle/apps/sector/migrations/0001_initial.py @@ -51,7 +51,7 @@ class Migration(migrations.Migration): 'titles_in_first_line', models.BooleanField( default=True, - help_text='If not, column titles are: street_id,parity,min_housenumber,max_housenumber,sector_id,sector_name, …', + help_text='If not, column titles are: street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,sector_name, …', verbose_name='First line defines column titles', ), ), @@ -87,11 +87,13 @@ class Migration(migrations.Migration): ), ( 'min_housenumber', - models.PositiveIntegerField(default=0, verbose_name='Minimal house number'), + models.PositiveIntegerField(default=0, verbose_name='Minimum house number (included)'), ), ( 'max_housenumber', - models.PositiveIntegerField(default=999999, verbose_name='Maximal house number'), + models.PositiveIntegerField( + default=999999, verbose_name='Maximum house number (included)' + ), ), ( 'sector', diff --git a/passerelle/apps/sector/migrations/0002_sectorization_street_name.py b/passerelle/apps/sector/migrations/0002_sectorization_street_name.py new file mode 100644 index 00000000..2f19baa9 --- /dev/null +++ b/passerelle/apps/sector/migrations/0002_sectorization_street_name.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.19 on 2021-10-15 11:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sector', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='sectorization', + name='street_name', + field=models.CharField(blank=True, max_length=150, verbose_name='Street Name'), + ), + ] diff --git a/passerelle/apps/sector/models.py b/passerelle/apps/sector/models.py index f12feb59..cb18e763 100644 --- a/passerelle/apps/sector/models.py +++ b/passerelle/apps/sector/models.py @@ -43,7 +43,15 @@ PARITY_CHOICES = ( (PARITY_EVEN, _('even')), ) -CSV_TITLES = ['street_id', 'parity', 'min_housenumber', 'max_housenumber', 'sector_id', 'sector_name'] +CSV_TITLES = [ + 'street_id', + 'street_name', + 'parity', + 'min_housenumber', + 'max_housenumber', + 'sector_id', + 'sector_name', +] MAX_HOUSENUMBER = 999_999 @@ -194,6 +202,7 @@ class SectorResource(BaseResource): parity=parity, min_housenumber=min_housenumber, max_housenumber=max_housenumber, + street_name=row['street_name'], ) @endpoint( @@ -267,6 +276,7 @@ class SectorResource(BaseResource): writer.writerow( [ sectorization.street_id, + sectorization.street_name, parity.get(sectorization.parity, mix), sectorization.min_housenumber if (limits or sectorization.min_housenumber) else '', sectorization.max_housenumber @@ -351,6 +361,7 @@ class Sector(models.Model): class Sectorization(models.Model): sector = models.ForeignKey(Sector, on_delete=models.CASCADE, verbose_name=_('Sector')) street_id = models.CharField(max_length=64, verbose_name=_('Street Identifier')) + street_name = models.CharField(max_length=150, verbose_name=_('Street Name'), blank=True) parity = models.SmallIntegerField( choices=PARITY_CHOICES, default=PARITY_ALL, verbose_name=_('Parity of numbers') ) @@ -365,8 +376,12 @@ class Sectorization(models.Model): ordering = ['street_id', 'min_housenumber', 'parity'] def __str__(self): + if self.street_name: + street = '%s (%s)' % (self.street_id, self.street_name) + else: + street = self.street_id return '%s, parity:%s, min:%s, max:%s → %s' % ( - self.street_id, + street, dict(PARITY_CHOICES).get(self.parity), self.min_housenumber, self.max_housenumber, diff --git a/tests/test_address.py b/tests/test_address.py index 4f5de827..1c483ef4 100644 --- a/tests/test_address.py +++ b/tests/test_address.py @@ -206,11 +206,11 @@ BAN = { "version": "draft", } -CSV = """street_id,parity,min_housenumber,max_housenumber,sector_id,sector_name -75114_1912,P,,,gs-moulin,Groupe Scolaire Moulin -75114_1912,I,0,167,gs-zola,Groupe Scolaire Zola -75114_1912,I,168,999999,ecole-hugo,École Hugo -75114_1913,,,,ecole-pascal,École Pascal +CSV = """street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,sector_name +75114_1912,rue du Château,P,,,gs-moulin,Groupe Scolaire Moulin +75114_1912,rue du Château,I,0,167,gs-zola,Groupe Scolaire Zola +75114_1912,rue du Château,I,168,999999,ecole-hugo,École Hugo +75114_1913,rue 1913,,,,ecole-pascal,École Pascal """ diff --git a/tests/test_import_export.py b/tests/test_import_export.py index 17fcd505..dde47cfe 100644 --- a/tests/test_import_export.py +++ b/tests/test_import_export.py @@ -47,8 +47,8 @@ data = """121;69981;DELANOUE;Eliot;H data_bom = force_text(data, 'utf-8').encode('utf-8-sig') -SECTOR_CSV = """street_id,parity,min_housenumber,max_housenumber,sector_id,sector_name -38 75114_1912,P,,, gs-moulin, Groupe Scolaire Moulin""" +SECTOR_CSV = """street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,sector_name +75114_1912,rue du Château,P,,, gs-moulin, Groupe Scolaire Moulin""" pytestmark = pytest.mark.django_db diff --git a/tests/test_sector.py b/tests/test_sector.py index 4cc2cabf..4e6583e5 100644 --- a/tests/test_sector.py +++ b/tests/test_sector.py @@ -34,43 +34,43 @@ from test_manager import login from passerelle.apps.sector.models import Sectorization, SectorResource from passerelle.base.models import AccessRight -CSV = """street_id,parity,min_housenumber,max_housenumber,sector_id,sector_name -75114_1912,P,,, gs-moulin, Groupe Scolaire Moulin -75114_1912,I,0,999999,gs-zola,Groupe Scolaire Zola -75114_1913,N,0,999999,ecole-hugo,École Hugo -75114_1914,,,10,ecole-hugo, École Hugo +CSV = """street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,sector_name +75114_1912,rue du Château,P,,, gs-moulin, Groupe Scolaire Moulin +75114_1912,rue du Château,I,0,999999,gs-zola,Groupe Scolaire Zola +75114_1913,rue des Moulins ,N,0,999999,ecole-hugo,École Hugo +75114_1914,rue du Vent,,,10,ecole-hugo, École Hugo -75114_1914,,11,, ecole-hugo2, École Hugo 2 -75114_1915,,,,ecole-hugo2 , École Hugo 2 +75114_1914,rue du Vent,,11,, ecole-hugo2, École Hugo 2 +75114_1915, ,,,,ecole-hugo2 , École Hugo 2 """ CSV_BOM = force_str(force_text(CSV, 'utf-8').encode('utf-8-sig')) -CSV_NO_FIRST_LINE = """75114_1912,P,,, gs-moulin, Groupe Scolaire Moulin -75114_1912,I,0,999999,gs-zola,Groupe Scolaire Zola -75114_1913,N,0,999999,ecole-hugo,École Hugo -75114_1914,,,10,ecole-hugo, École Hugo +CSV_NO_FIRST_LINE = """75114_1912,rue du Château,P,,, gs-moulin, Groupe Scolaire Moulin +75114_1912,rue du Château,I,0,999999,gs-zola,Groupe Scolaire Zola +75114_1913,,N,0,999999,ecole-hugo,École Hugo +75114_1914,rue du Vent,,,10,ecole-hugo, École Hugo -75114_1914,,11,, ecole-hugo, École Hugo""" +75114_1914,rue du Vent,,11,, ecole-hugo, École Hugo""" -CSV_REORDERED = """sector_id,sector_name,street_id,parity,min_housenumber,max_housenumber,foo,bar -gs-moulin, Groupe Scolaire Moulin, 75114_1912,P,,,aaa,bbb -gs-zola,Groupe Scolaire Zola,75114_1912,I,0,999999,xxx,yyy -ecole-hugo,École Hugo,75114_1913,N,0,999999,000,1 -,,75114_1999,N,0,999999,, +CSV_REORDERED = """sector_id,sector_name,street_id,parity,min_housenumber,max_housenumber,foo,street_name,bar +gs-moulin, Groupe Scolaire Moulin, 75114_1912,P,,,aaa,rue du Château,bbb +gs-zola,Groupe Scolaire Zola,75114_1912,I,0,999999,xxx,rue du Château,yyy +ecole-hugo,École Hugo,75114_1913,N,0,999999,000,rue des Moulins,1 +,,75114_1999,N,0,999999,,avenue 999, """ -CSV_MISSING_COLUMN = """street_id,min_housenumber,max_housenumber,sector_id,sector_name -75114_1912,,,foo, -,0,999999,gs-zola,Groupe Scolaire Zola""" +CSV_MISSING_COLUMN = """street_id,street_name,min_housenumber,max_housenumber,sector_id,sector_name +75114_1912,,,,foo, +,,0,999999,gs-zola,Groupe Scolaire Zola""" -CSV_MISSING_SECTOR = """street_id,parity,min_housenumber,max_housenumber,sector_id,sector_name -75114_1912,P,,, , -75114_1912,I,0,999999,gs-zola,Groupe Scolaire Zola""" +CSV_MISSING_SECTOR = """street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,sector_name +75114_1912,rue du Château,P,,, , +75114_1912,rue du Château,I,0,999999,gs-zola,Groupe Scolaire Zola""" -CSV_MISSING_STREET = """street_id,parity,min_housenumber,max_housenumber,sector_id,sector_name -75114_1912,P,,,foo, -,I,0,999999,gs-zola,Groupe Scolaire Zola""" +CSV_MISSING_STREET = """street_id,street_name,parity,min_housenumber,max_housenumber,sector_id,sector_name +75114_1912,,P,,,foo, +,,I,0,999999,gs-zola,Groupe Scolaire Zola""" pytestmark = pytest.mark.django_db @@ -89,6 +89,19 @@ def sector(db): def test_sector_creation(sector): assert '%s' % sector == 'title [test]' assert sector.sector_set.count() == 4 + rue1913 = Sectorization.objects.get(street_id='75114_1913') + assert rue1913.street_name == 'rue des Moulins' + assert ( + '%s' % rue1913 + == '75114_1913 (rue des Moulins), parity:all, min:0, max:999999 → title [test] > École Hugo [ecole-hugo]' + ) + rue1915 = Sectorization.objects.get(street_id='75114_1915') + assert rue1915.street_name == '' + assert ( + '%s' % rue1915 + == '75114_1915, parity:all, min:0, max:999999 → title [test] > École Hugo 2 [ecole-hugo2]' + ) + hugo = sector.sector_set.get(slug='ecole-hugo') assert Sectorization.objects.filter(sector=hugo).count() == 2 hugo2 = sector.sector_set.get(slug='gs-zola') @@ -242,7 +255,7 @@ def test_sector_endpoint_export(app, sector): resp = app.get(url) assert resp.headers['content-type'] == 'text/csv' assert resp.text.startswith( - '"street_id","parity","min_housenumber","max_housenumber","sector_id","sector_name"' + '"street_id","street_name","parity","min_housenumber","max_housenumber","sector_id","sector_name"' ) assert len(resp.text.splitlines()) == 7 sector.titles_in_first_line = False