From 0fb9c23b7b9833fe29bbe3bb398dca952f701406 Mon Sep 17 00:00:00 2001
From: Serghei Mihai <smihai@entrouvert.com>
Date: Thu, 14 Mar 2019 14:13:05 +0100
Subject: [PATCH] agendas: add new booking's label attribute for user
 presentation purposes (#25820)

Use the new label in ICS summary
---
 .../0026_booking_user_display_label.py        | 20 +++++++++++++++++++
 chrono/agendas/models.py                      |  3 ++-
 chrono/api/views.py                           |  2 ++
 tests/test_api.py                             | 14 +++++++++++--
 4 files changed, 36 insertions(+), 3 deletions(-)
 create mode 100644 chrono/agendas/migrations/0026_booking_user_display_label.py

diff --git a/chrono/agendas/migrations/0026_booking_user_display_label.py b/chrono/agendas/migrations/0026_booking_user_display_label.py
new file mode 100644
index 0000000..94a024e
--- /dev/null
+++ b/chrono/agendas/migrations/0026_booking_user_display_label.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-03-14 15:06
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('agendas', '0025_auto_20181206_1252'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='booking',
+            name='user_display_label',
+            field=models.CharField(blank=True, max_length=250, verbose_name='Label displayed to user'),
+        ),
+    ]
diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py
index 6796f7e..3eea87a 100644
--- a/chrono/agendas/models.py
+++ b/chrono/agendas/models.py
@@ -365,6 +365,7 @@ class Booking(models.Model):
             on_delete=models.CASCADE, related_name='secondary_booking_set')
 
     label = models.CharField(max_length=250, blank=True)
+    user_display_label = models.CharField(verbose_name=_('Label displayed to user'), max_length=250, blank=True)
     user_name = models.CharField(max_length=250, blank=True)
     backoffice_url = models.URLField(blank=True)
 
@@ -395,7 +396,7 @@ class Booking(models.Model):
         vevent = vobject.newFromBehavior('vevent')
         vevent.add('uid').value = '%s-%s-%s' % (self.event.start_datetime.isoformat(), self.event.agenda.pk, self.pk)
 
-        vevent.add('summary').value = self.label
+        vevent.add('summary').value = self.user_display_label or self.label
         vevent.add('dtstart').value = self.event.start_datetime
         if self.user_name:
             vevent.add('attendee').value = self.user_name
diff --git a/chrono/api/views.py b/chrono/api/views.py
index 60ca4a1..c6fe25c 100644
--- a/chrono/api/views.py
+++ b/chrono/api/views.py
@@ -308,6 +308,7 @@ class SlotSerializer(serializers.Serializer):
     '''
     label = serializers.CharField(max_length=250, allow_blank=True) #, required=False)
     user_name = serializers.CharField(max_length=250, allow_blank=True) #, required=False)
+    user_display_label = serializers.CharField(max_length=250, allow_blank=True)
     backoffice_url = serializers.URLField(allow_blank=True) # , required=False)
     count = serializers.IntegerField(min_value=1) # , required=False)
 
@@ -451,6 +452,7 @@ class Fillslots(APIView):
                                       label=payload.get('label', ''),
                                       user_name=payload.get('user_name', ''),
                                       backoffice_url=payload.get('backoffice_url', ''),
+                                      user_display_label=payload.get('user_display_label', ''),
                                       extra_data=extra_data)
                 if primary_booking is not None:
                     new_booking.primary_booking = primary_booking
diff --git a/tests/test_api.py b/tests/test_api.py
index 3779dea..eee0c10 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -404,11 +404,21 @@ def test_booking_ics(app, some_data, meetings_agenda, user):
     assert 'ATTENDEE:bar\r\n' in booking_ics
     assert 'URL:http://example.com/booking\r\n' in booking_ics
 
+    # test with user_label in additionnal data
+    resp = app.post_json('/api/agenda/%s/fillslot/%s/' % (agenda.id, event.id),
+            params={'label': 'foo', 'user_name': 'bar', 'backoffice_url': 'http://example.net/',
+                    'url': 'http://example.com/booking', 'user_display_label': 'your booking'})
+    assert Booking.objects.count() == 3
+    booking_ics = Booking.objects.get(id=resp.json['booking_id']).get_ics()
+    assert 'SUMMARY:your booking\r\n' in booking_ics
+    assert 'ATTENDEE:bar\r\n' in booking_ics
+    assert 'URL:http://example.com/booking\r\n' in booking_ics
+
     # extra data stored in extra_data field
     resp = app.post_json('/api/agenda/%s/fillslot/%s/' % (agenda.id, event.id),
             params={'label': 'l', 'user_name': 'u', 'backoffice_url': '', 'location': 'bar',
                     'comment': 'booking comment', 'description': 'booking description'})
-    assert Booking.objects.count() == 3
+    assert Booking.objects.count() == 4
     booking_id = resp.json['booking_id']
     booking = Booking.objects.get(id=booking_id)
     booking_ics = booking.get_ics()
@@ -437,7 +447,7 @@ def test_booking_ics(app, some_data, meetings_agenda, user):
     resp = app.get('/api/agenda/meetings/%s/datetimes/' % meeting_type.id)
     event = resp.json['data'][2]
     resp = app.post('/api/agenda/%s/fillslot/%s/' % (meetings_agenda_id, event['id']))
-    assert Booking.objects.count() == 4
+    assert Booking.objects.count() == 5
     assert 'ics_url' in resp.json['api']
     booking = Booking.objects.get(id=resp.json['booking_id'])
     booking_ics = booking.get_ics()
-- 
2.20.1

