From b36b8d503a8f18181ae8eb098ae06883a0586ace Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= <mordae@anilinux.org>
Date: Tue, 17 Aug 2021 17:34:08 +0200
Subject: [PATCH] elections2021: Add a CSV export of banner orders
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Jan Hamal Dvořák <mordae@anilinux.org>
---
 .../migrations/0038_auto_20210817_1303.py     | 264 ++++++++++++++++--
 .../0039_elections2021mappage_subtitle.py     |  10 +-
 ...me_place_of_birth_bannerorder_residency.py |  18 ++
 elections2021/migrations/0041_token.py        |  22 ++
 elections2021/models.py                       |  87 +++---
 .../elections2021/banner_order_form.html      |   8 +-
 elections2021/views.py                        |  20 ++
 majak/urls.py                                 |   6 +
 8 files changed, 366 insertions(+), 69 deletions(-)
 create mode 100644 elections2021/migrations/0040_rename_place_of_birth_bannerorder_residency.py
 create mode 100644 elections2021/migrations/0041_token.py
 create mode 100644 elections2021/views.py

diff --git a/elections2021/migrations/0038_auto_20210817_1303.py b/elections2021/migrations/0038_auto_20210817_1303.py
index 0a37bbd2..f56e2f7d 100644
--- a/elections2021/migrations/0038_auto_20210817_1303.py
+++ b/elections2021/migrations/0038_auto_20210817_1303.py
@@ -1,55 +1,261 @@
 # Generated by Django 3.2.5 on 2021-08-17 11:03
 
-from django.db import migrations, models
 import django.db.models.deletion
-import shared.models
 import wagtail.core.blocks
 import wagtail.core.fields
 import wagtail.images.blocks
 import wagtailmetadata.models
+from django.db import migrations, models
+
+import shared.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('wagtailimages', '0023_add_choose_permissions'),
-        ('wagtailcore', '0062_comment_models_and_pagesubscription'),
-        ('elections2021', '0037_bannerorder_elections2021bannerlistpage'),
+        ("wagtailimages", "0023_add_choose_permissions"),
+        ("wagtailcore", "0062_comment_models_and_pagesubscription"),
+        ("elections2021", "0037_bannerorder_elections2021bannerlistpage"),
     ]
 
     operations = [
         migrations.AlterModelOptions(
-            name='elections2021bannerlistpage',
-            options={'verbose_name': 'nabídka plachet'},
+            name="elections2021bannerlistpage",
+            options={"verbose_name": "nabídka plachet"},
         ),
         migrations.AlterField(
-            model_name='elections2021bannerlistpage',
-            name='banners',
-            field=wagtail.core.fields.StreamField([('banners', wagtail.core.blocks.StructBlock([('code', wagtail.core.blocks.CharBlock(label='kód banneru')), ('candidate1', wagtail.core.blocks.CharBlock(label='první kandidát', required=False)), ('candidate2', wagtail.core.blocks.CharBlock(label='druhý kandidát', required=False)), ('tagline', wagtail.core.blocks.CharBlock(label='slogan', required=False)), ('preview', wagtail.images.blocks.ImageChooserBlock(label='náhled'))]))], blank=True, verbose_name='objednávání plachet'),
+            model_name="elections2021bannerlistpage",
+            name="banners",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "banners",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "code",
+                                    wagtail.core.blocks.CharBlock(label="kód banneru"),
+                                ),
+                                (
+                                    "candidate1",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="první kandidát", required=False
+                                    ),
+                                ),
+                                (
+                                    "candidate2",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="druhý kandidát", required=False
+                                    ),
+                                ),
+                                (
+                                    "tagline",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="slogan", required=False
+                                    ),
+                                ),
+                                (
+                                    "preview",
+                                    wagtail.images.blocks.ImageChooserBlock(
+                                        label="náhled"
+                                    ),
+                                ),
+                            ]
+                        ),
+                    )
+                ],
+                blank=True,
+                verbose_name="objednávání plachet",
+            ),
         ),
         migrations.CreateModel(
-            name='Elections2021MapPage',
+            name="Elections2021MapPage",
             fields=[
-                ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
-                ('jihocesky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Jihočeský')),
-                ('jihomoravsky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Jihomoravsý')),
-                ('karlovarsky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Karlovarský')),
-                ('kralovehradecky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Královéhradecký')),
-                ('liberecky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Liberecký')),
-                ('moravskoslezsky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Moravskoslezský')),
-                ('olomoucky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Olomoucký')),
-                ('pardubicky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Pardubický')),
-                ('plzensky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Plzeňský')),
-                ('praha', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Praha')),
-                ('search_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Search image')),
-                ('stredocesky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Středočeský')),
-                ('ustecky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Ústecký')),
-                ('vysocina', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Vysočina')),
-                ('zlinsky', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.page', verbose_name='Zlínský')),
+                (
+                    "page_ptr",
+                    models.OneToOneField(
+                        auto_created=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        parent_link=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="wagtailcore.page",
+                    ),
+                ),
+                (
+                    "jihocesky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Jihočeský",
+                    ),
+                ),
+                (
+                    "jihomoravsky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Jihomoravsý",
+                    ),
+                ),
+                (
+                    "karlovarsky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Karlovarský",
+                    ),
+                ),
+                (
+                    "kralovehradecky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Královéhradecký",
+                    ),
+                ),
+                (
+                    "liberecky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Liberecký",
+                    ),
+                ),
+                (
+                    "moravskoslezsky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Moravskoslezský",
+                    ),
+                ),
+                (
+                    "olomoucky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Olomoucký",
+                    ),
+                ),
+                (
+                    "pardubicky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Pardubický",
+                    ),
+                ),
+                (
+                    "plzensky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Plzeňský",
+                    ),
+                ),
+                (
+                    "praha",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Praha",
+                    ),
+                ),
+                (
+                    "search_image",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailimages.image",
+                        verbose_name="Search image",
+                    ),
+                ),
+                (
+                    "stredocesky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Středočeský",
+                    ),
+                ),
+                (
+                    "ustecky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Ústecký",
+                    ),
+                ),
+                (
+                    "vysocina",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Vysočina",
+                    ),
+                ),
+                (
+                    "zlinsky",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailcore.page",
+                        verbose_name="Zlínský",
+                    ),
+                ),
             ],
             options={
-                'verbose_name': 'mapa krajů',
+                "verbose_name": "mapa krajů",
             },
-            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+            bases=(
+                shared.models.SubpageMixin,
+                wagtailmetadata.models.WagtailImageMetadataMixin,
+                "wagtailcore.page",
+                models.Model,
+            ),
         ),
     ]
diff --git a/elections2021/migrations/0039_elections2021mappage_subtitle.py b/elections2021/migrations/0039_elections2021mappage_subtitle.py
index 827b845f..c839d30e 100644
--- a/elections2021/migrations/0039_elections2021mappage_subtitle.py
+++ b/elections2021/migrations/0039_elections2021mappage_subtitle.py
@@ -6,13 +6,15 @@ from django.db import migrations, models
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('elections2021', '0038_auto_20210817_1303'),
+        ("elections2021", "0038_auto_20210817_1303"),
     ]
 
     operations = [
         migrations.AddField(
-            model_name='elections2021mappage',
-            name='subtitle',
-            field=models.CharField(blank=True, max_length=100, verbose_name='podtitulek'),
+            model_name="elections2021mappage",
+            name="subtitle",
+            field=models.CharField(
+                blank=True, max_length=100, verbose_name="podtitulek"
+            ),
         ),
     ]
diff --git a/elections2021/migrations/0040_rename_place_of_birth_bannerorder_residency.py b/elections2021/migrations/0040_rename_place_of_birth_bannerorder_residency.py
new file mode 100644
index 00000000..53644f90
--- /dev/null
+++ b/elections2021/migrations/0040_rename_place_of_birth_bannerorder_residency.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.5 on 2021-08-17 15:04
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('elections2021', '0039_elections2021mappage_subtitle'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='bannerorder',
+            old_name='place_of_birth',
+            new_name='residency',
+        ),
+    ]
diff --git a/elections2021/migrations/0041_token.py b/elections2021/migrations/0041_token.py
new file mode 100644
index 00000000..c0a22302
--- /dev/null
+++ b/elections2021/migrations/0041_token.py
@@ -0,0 +1,22 @@
+# Generated by Django 3.2.5 on 2021-08-17 15:17
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('elections2021', '0040_rename_place_of_birth_bannerorder_residency'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Token',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('scope', models.CharField(max_length=127)),
+                ('bearer', models.CharField(max_length=40)),
+                ('comment', models.CharField(max_length=255)),
+            ],
+        ),
+    ]
diff --git a/elections2021/models.py b/elections2021/models.py
index 4687d549..a463a62d 100644
--- a/elections2021/models.py
+++ b/elections2021/models.py
@@ -2450,6 +2450,12 @@ class Elections2021CalendarPage(SubpageMixin, MetadataPageMixin, CalendarMixin,
         return self.calendar
 
 
+class Token(models.Model):
+    scope = models.CharField(max_length=127)
+    bearer = models.CharField(max_length=40)
+    comment = models.CharField(max_length=255)
+
+
 class BannerBlock(blocks.StructBlock):
     code = blocks.CharBlock(label="kód banneru")
     candidate1 = blocks.CharBlock(label="první kandidát", required=False)
@@ -2467,7 +2473,7 @@ class BannerOrder(models.Model):
     code = models.CharField(max_length=10)
     name = models.CharField(max_length=35)
     surname = models.CharField(max_length=70)
-    place_of_birth = models.CharField(max_length=70)
+    residency = models.CharField(max_length=70)
     date_of_birth = models.DateField()
     phone = models.CharField(max_length=20)
     email = models.EmailField(max_length=70)
@@ -2480,7 +2486,7 @@ class BannerForm(forms.ModelForm):
             "code",
             "name",
             "surname",
-            "place_of_birth",
+            "residency",
             "date_of_birth",
             "phone",
             "email",
@@ -2551,7 +2557,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
 
     subtitle = models.CharField(max_length=100, blank=True, verbose_name="podtitulek")
 
-    praha = models.ForeignKey("wagtailcore.Page",
+    praha = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Praha",
         null=True,
         blank=True,
@@ -2559,7 +2566,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    stredocesky = models.ForeignKey("wagtailcore.Page",
+    stredocesky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Středočeský",
         null=True,
         blank=True,
@@ -2567,7 +2575,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    jihocesky = models.ForeignKey("wagtailcore.Page",
+    jihocesky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Jihočeský",
         null=True,
         blank=True,
@@ -2575,7 +2584,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    plzensky = models.ForeignKey("wagtailcore.Page",
+    plzensky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Plzeňský",
         null=True,
         blank=True,
@@ -2583,7 +2593,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    karlovarsky = models.ForeignKey("wagtailcore.Page",
+    karlovarsky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Karlovarský",
         null=True,
         blank=True,
@@ -2591,7 +2602,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    ustecky = models.ForeignKey("wagtailcore.Page",
+    ustecky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Ústecký",
         null=True,
         blank=True,
@@ -2599,7 +2611,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    liberecky = models.ForeignKey("wagtailcore.Page",
+    liberecky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Liberecký",
         null=True,
         blank=True,
@@ -2607,7 +2620,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    kralovehradecky = models.ForeignKey("wagtailcore.Page",
+    kralovehradecky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Královéhradecký",
         null=True,
         blank=True,
@@ -2615,7 +2629,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    moravskoslezsky = models.ForeignKey("wagtailcore.Page",
+    moravskoslezsky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Moravskoslezský",
         null=True,
         blank=True,
@@ -2623,7 +2638,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    pardubicky = models.ForeignKey("wagtailcore.Page",
+    pardubicky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Pardubický",
         null=True,
         blank=True,
@@ -2631,7 +2647,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    vysocina = models.ForeignKey("wagtailcore.Page",
+    vysocina = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Vysočina",
         null=True,
         blank=True,
@@ -2639,7 +2656,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    jihomoravsky = models.ForeignKey("wagtailcore.Page",
+    jihomoravsky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Jihomoravsý",
         null=True,
         blank=True,
@@ -2647,7 +2665,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    olomoucky = models.ForeignKey("wagtailcore.Page",
+    olomoucky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Olomoucký",
         null=True,
         blank=True,
@@ -2655,7 +2674,8 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
         related_name="+",
     )
 
-    zlinsky = models.ForeignKey("wagtailcore.Page",
+    zlinsky = models.ForeignKey(
+        "wagtailcore.Page",
         verbose_name="Zlínský",
         null=True,
         blank=True,
@@ -2667,22 +2687,25 @@ class Elections2021MapPage(SubpageMixin, MetadataPageMixin, Page):
 
     content_panels = Page.content_panels + [
         FieldPanel("subtitle"),
-        MultiFieldPanel([
-            PageChooserPanel("praha", "wagtailcore.Page"),
-            PageChooserPanel("stredocesky", "wagtailcore.Page"),
-            PageChooserPanel("jihocesky", "wagtailcore.Page"),
-            PageChooserPanel("plzensky", "wagtailcore.Page"),
-            PageChooserPanel("karlovarsky", "wagtailcore.Page"),
-            PageChooserPanel("ustecky", "wagtailcore.Page"),
-            PageChooserPanel("liberecky", "wagtailcore.Page"),
-            PageChooserPanel("kralovehradecky", "wagtailcore.Page"),
-            PageChooserPanel("moravskoslezsky", "wagtailcore.Page"),
-            PageChooserPanel("pardubicky", "wagtailcore.Page"),
-            PageChooserPanel("vysocina", "wagtailcore.Page"),
-            PageChooserPanel("jihomoravsky", "wagtailcore.Page"),
-            PageChooserPanel("olomoucky", "wagtailcore.Page"),
-            PageChooserPanel("zlinsky", "wagtailcore.Page"),
-        ], "Rozcestník krajů"),
+        MultiFieldPanel(
+            [
+                PageChooserPanel("praha", "wagtailcore.Page"),
+                PageChooserPanel("stredocesky", "wagtailcore.Page"),
+                PageChooserPanel("jihocesky", "wagtailcore.Page"),
+                PageChooserPanel("plzensky", "wagtailcore.Page"),
+                PageChooserPanel("karlovarsky", "wagtailcore.Page"),
+                PageChooserPanel("ustecky", "wagtailcore.Page"),
+                PageChooserPanel("liberecky", "wagtailcore.Page"),
+                PageChooserPanel("kralovehradecky", "wagtailcore.Page"),
+                PageChooserPanel("moravskoslezsky", "wagtailcore.Page"),
+                PageChooserPanel("pardubicky", "wagtailcore.Page"),
+                PageChooserPanel("vysocina", "wagtailcore.Page"),
+                PageChooserPanel("jihomoravsky", "wagtailcore.Page"),
+                PageChooserPanel("olomoucky", "wagtailcore.Page"),
+                PageChooserPanel("zlinsky", "wagtailcore.Page"),
+            ],
+            "Rozcestník krajů",
+        ),
     ]
 
     promote_panels = [
diff --git a/elections2021/templates/elections2021/banner_order_form.html b/elections2021/templates/elections2021/banner_order_form.html
index 7df2ded7..c9942e8d 100644
--- a/elections2021/templates/elections2021/banner_order_form.html
+++ b/elections2021/templates/elections2021/banner_order_form.html
@@ -45,12 +45,12 @@
           {% endfor %}
         </div>
 
-        <div class="form-field col-span-2 form-field-required {% if request.banner_form.errors.place_of_birth %}form-field--error{% endif %}">
-          <label class="form-field__label" for="place_of_birth">Místo narození</label>
+        <div class="form-field col-span-2 form-field-required {% if request.banner_form.errors.residency %}form-field--error{% endif %}">
+          <label class="form-field__label" for="residency">Obec trvalého pobytu</label>
           <div class="form-field__wrapper form-field__wrapper--shadowed">
-            <input type="text" class="text-input form-field__control text-black" id="place_of_birth" name="place_of_birth" value="{{request.banner_form.place_of_birth.value|default_if_none:""}}" placeholder="Sedlíšťka" />
+            <input type="text" class="text-input form-field__control text-black" id="residency" name="residency" value="{{request.banner_form.residency.value|default_if_none:""}}" placeholder="Sedlíšťka" />
           </div>
-          {% for error in request.banner_form.errors.place_of_birth %}
+          {% for error in request.banner_form.errors.residency %}
           <div class="form-field__error">{{error}}</div>
           {% endfor %}
         </div>
diff --git a/elections2021/views.py b/elections2021/views.py
new file mode 100644
index 00000000..7ef2e82b
--- /dev/null
+++ b/elections2021/views.py
@@ -0,0 +1,20 @@
+import csv
+from .models import BannerOrder, Token
+from django.http import HttpResponse, HttpResponseForbidden
+
+
+def banner_orders_csv(request):
+    response = HttpResponse(content_type='text/csv;charset=utf-8')
+
+    tokens = Token.objects.filter(bearer=request.GET.get('token'), scope="banner-orders")
+    if not tokens:
+        return HttpResponseForbidden()
+
+    w = csv.writer(response)
+    w.writerow(["ID", "Plachta", "Jméno", "Příjmení", "Bydliště", "Narozen", "Telefon", "Mail"])
+
+    for row in BannerOrder.objects.all():
+        w.writerow([str(row.id), row.code, row.name, row.surname, row.residency,
+                    str(row.date_of_birth), row.phone, row.email])
+
+    return response
diff --git a/majak/urls.py b/majak/urls.py
index 44cf8412..5f18ce5c 100644
--- a/majak/urls.py
+++ b/majak/urls.py
@@ -7,6 +7,7 @@ from wagtail.admin import urls as wagtailadmin_urls
 from wagtail.core import urls as wagtail_urls
 from wagtail.documents import urls as wagtaildocs_urls
 
+from elections2021 import views as elections2021_views
 from search import views as search_views
 
 urlpatterns = [
@@ -14,6 +15,11 @@ urlpatterns = [
     url(r"^admin/", include(wagtailadmin_urls)),
     url(r"^documents/", include(wagtaildocs_urls)),
     url(r"^search/$", search_views.search, name="search"),
+    url(
+        r"^export/elections2021/banner-orders.csv$",
+        elections2021_views.banner_orders_csv,
+        name="elections2021_banner_orders_csv",
+    ),
     url(r"^captcha/", include(captcha.urls)),
 ] + pirates_urlpatterns
 
-- 
GitLab