manager: use user_block also in meetings agenda views (#63915)
This commit is contained in:
parent
50963bb083
commit
efad2bdc29
|
@ -776,10 +776,17 @@ class Agenda(models.Model):
|
|||
return [x.strip() for x in self.booking_check_filters.split(',')]
|
||||
|
||||
def get_booking_user_block_template(self):
|
||||
return (
|
||||
self.booking_user_block_template
|
||||
or '{{ booking.user_name|default:booking.label|default:"%s" }}' % _('Anonymous')
|
||||
)
|
||||
if self.kind == 'events':
|
||||
default = '{{ booking.user_name|default:booking.label|default:"%s" }}' % _('Anonymous')
|
||||
else:
|
||||
default = """{%% if booking.label and booking.user_name %%}
|
||||
{{ booking.label }} - {{ booking.user_name }}
|
||||
{%% else %%}
|
||||
{{ booking.user_name|default:booking.label|default:"%s" }}
|
||||
{%% endif %%}""" % _(
|
||||
'booked'
|
||||
)
|
||||
return self.booking_user_block_template or default
|
||||
|
||||
def get_recurrence_exceptions(self, min_start, max_start):
|
||||
return TimePeriodException.objects.filter(
|
||||
|
@ -2075,14 +2082,6 @@ class Booking(models.Model):
|
|||
name = self.user_name or self.label or _('Anonymous')
|
||||
return '%s, %s' % (name, date_format(localtime(self.creation_datetime), 'DATETIME_FORMAT'))
|
||||
|
||||
def meetings_display(self):
|
||||
if self.label and self.user_name:
|
||||
return '%s - %s' % (self.label, self.user_name)
|
||||
elif self.label or self.user_name:
|
||||
return self.label or self.user_name
|
||||
else:
|
||||
return ugettext('booked')
|
||||
|
||||
def get_form_url(self):
|
||||
return translate_from_publik_url(self.form_url)
|
||||
|
||||
|
|
|
@ -1297,9 +1297,15 @@ class AgendaDisplaySettingsForm(forms.ModelForm):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['booking_user_block_template'].help_text = (
|
||||
_('Displayed for each booking in event page and check page'),
|
||||
)
|
||||
if kwargs['instance'].kind == 'events':
|
||||
self.fields['booking_user_block_template'].help_text = (
|
||||
_('Displayed for each booking in event page and check page'),
|
||||
)
|
||||
else:
|
||||
self.fields['booking_user_block_template'].help_text = (
|
||||
_('Displayed for each booking in agenda view pages'),
|
||||
)
|
||||
del self.fields['event_display_template']
|
||||
|
||||
|
||||
class AgendaBookingCheckSettingsForm(forms.ModelForm):
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<div class="booking{% if booking.color %} booking-color-{{ booking.color.index }}{% endif %}"
|
||||
style="height: {{ booking.css_height }}%; min-height: {{ booking.css_height }}%; top: {{ booking.css_top }}%;"
|
||||
><span class="start-time">{{booking.event.start_datetime|date:"TIME_FORMAT"}}</span>
|
||||
<a {% if booking.get_backoffice_url %}href="{{booking.get_backoffice_url}}"{% endif %}>{{ booking.meetings_display }}</a>
|
||||
<a {% if booking.get_backoffice_url %}href="{{booking.get_backoffice_url}}"{% endif %}>{{ booking.get_user_block }}</a>
|
||||
<a rel="popup" class="cancel" href="{% url 'chrono-manager-booking-cancel' pk=booking.event.agenda_id booking_pk=booking.pk %}?next={{ request.path }}">{% trans "Cancel" %}</a>
|
||||
{% if booking.color %}<span class="booking-color-label booking-bg-color-{{ booking.color.index }}">{{ booking.color }}</span>{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
{% for slot in day.infos.booked_slots %}
|
||||
<div class="booking{% if slot.booking.color %} booking-color-{{ slot.booking.color.index }}{% endif %}" style="left:{{ slot.css_left|stringformat:".1f" }}%;height:{{ slot.css_height|stringformat:".1f" }}%;min-height:{{ slot.css_height|stringformat:".1f" }}%;top:{{ slot.css_top|stringformat:".1f" }}%;width:{{ slot.css_width|stringformat:".1f" }}%;">
|
||||
<span class="start-time">{{slot.booking.event.start_datetime|date:"TIME_FORMAT"}}</span>
|
||||
<a {% if slot.booking.get_backoffice_url %}href="{{slot.booking.get_backoffice_url}}"{% endif %}>{{ slot.booking.meetings_display }}</a>
|
||||
<a {% if slot.booking.get_backoffice_url %}href="{{slot.booking.get_backoffice_url}}"{% endif %}>{{ slot.booking.get_user_block }}</a>
|
||||
<a rel="popup" class="cancel" href="{% url 'chrono-manager-booking-cancel' pk=slot.booking.event.agenda_id booking_pk=slot.booking.id %}?next={{ request.path }}">{% trans "Cancel" %}</a>
|
||||
{% if not single_desk %}<span class="desk">{{ slot.desk }}</span>{% endif %}
|
||||
{% if slot.booking.color %}<span class="booking-color-label booking-bg-color-{{ slot.booking.color.index }}">{{ slot.booking.color }}</span>{% endif %}
|
||||
|
|
|
@ -153,4 +153,18 @@
|
|||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<div class="section">
|
||||
<h3>{% trans "Display options" %}
|
||||
<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
|
||||
</h3>
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
{% trans "Booking display template:" %}
|
||||
<pre>{{ agenda.get_booking_user_block_template }}</pre>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<div class="booking"
|
||||
style="height: {{ booking.css_height }}%; min-height: {{ booking.css_height }}%; top: {{ booking.css_top }}%;"
|
||||
><span class="start-time">{{ booking.event.start_datetime|date:"TIME_FORMAT" }}</span>
|
||||
<a {% if booking.get_backoffice_url %}href="{{ booking.get_backoffice_url }}"{% endif %}>{{ booking.meetings_display }}</a>
|
||||
<a {% if booking.get_backoffice_url %}href="{{ booking.get_backoffice_url }}"{% endif %}>{{ booking.get_user_block }}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
{% for slot in day.infos.booked_slots %}
|
||||
<div class="booking" style="height:{{ slot.css_height|stringformat:".1f" }}%;min-height:{{ slot.css_height|stringformat:".1f" }}%;top:{{ slot.css_top|stringformat:".1f" }}%">
|
||||
<span class="start-time">{{ slot.booking.event.start_datetime|date:"TIME_FORMAT" }}</span>
|
||||
<a {% if slot.booking.get_backoffice_url %}href="{{ slot.booking.get_backoffice_url }}"{% endif %}>{{ booking.meetings_display }}</a>
|
||||
<a {% if slot.booking.get_backoffice_url %}href="{{ slot.booking.get_backoffice_url }}"{% endif %}>{{ slot.booking.get_user_block }}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
@ -283,7 +283,9 @@ class ResourceDayView(DateMixin, DayArchiveView):
|
|||
|
||||
def get_queryset(self):
|
||||
queryset = (
|
||||
self.resource.event_set.all().select_related('meeting_type').prefetch_related('booking_set')
|
||||
self.resource.event_set.all()
|
||||
.select_related('meeting_type', 'agenda')
|
||||
.prefetch_related('booking_set')
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
@ -398,7 +400,9 @@ class ResourceMonthView(DateMixin, MonthArchiveView):
|
|||
|
||||
def get_queryset(self):
|
||||
queryset = (
|
||||
self.resource.event_set.all().select_related('meeting_type').prefetch_related('booking_set')
|
||||
self.resource.event_set.all()
|
||||
.select_related('meeting_type', 'agenda')
|
||||
.prefetch_related('booking_set')
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
@ -1200,7 +1204,7 @@ class AgendaDisplaySettingsView(AgendaEditView):
|
|||
title = _("Configure display options")
|
||||
|
||||
def set_agenda(self, **kwargs):
|
||||
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events')
|
||||
self.agenda = get_object_or_404(Agenda.objects.exclude(kind='virtual'), pk=kwargs.get('pk'))
|
||||
|
||||
def get_initial(self):
|
||||
return {'booking_user_block_template': self.agenda.get_booking_user_block_template()}
|
||||
|
@ -1372,7 +1376,7 @@ class AgendaDateView(DateMixin, ViewableAgendaMixin):
|
|||
else:
|
||||
queryset = (
|
||||
Event.objects.filter(agenda__virtual_agendas=self.agenda)
|
||||
.select_related('meeting_type')
|
||||
.select_related('meeting_type', 'agenda')
|
||||
.prefetch_related('booking_set')
|
||||
)
|
||||
return queryset
|
||||
|
|
|
@ -524,10 +524,14 @@ def test_options_agenda_booking_display_options(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert 'syntax error' in resp.text
|
||||
|
||||
# check kind
|
||||
# and for meetings agenda
|
||||
agenda.kind = 'meetings'
|
||||
agenda.save()
|
||||
app.get(url, status=404)
|
||||
resp = app.get(url)
|
||||
assert 'event_display_template' not in resp.form.fields
|
||||
assert 'booking_user_block_template' in resp.form.fields
|
||||
|
||||
# check kind
|
||||
agenda.kind = 'virtual'
|
||||
agenda.save()
|
||||
app.get(url, status=404)
|
||||
|
@ -807,16 +811,28 @@ def test_agenda_day_view(app, admin_user, manager_user, api_user):
|
|||
booking_url = resp.json['data'][0]['api']['fillslot_url']
|
||||
booking_url2 = resp.json['data'][2]['api']['fillslot_url']
|
||||
resp = app.post(booking_url)
|
||||
resp = app.post_json(booking_url2, params={'label': 'foo', 'user': 'bar', 'url': 'http://baz/'})
|
||||
resp = app.post_json(
|
||||
booking_url2, params={'label': 'foo', 'user_last_name': "bar's", 'url': 'http://baz/'}
|
||||
)
|
||||
|
||||
app.reset()
|
||||
login(app)
|
||||
date = Booking.objects.all()[0].event.start_datetime
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day))
|
||||
assert resp.text.count('div class="booking') == 2
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "foo - bar's"
|
||||
assert 'foo - bar's' in resp
|
||||
assert 'hourspan-2' in resp.text # table CSS class
|
||||
assert 'height: 50%; top: 0%;' in resp.text # booking cells
|
||||
|
||||
agenda.booking_user_block_template = '<b>{{ booking.user_name }}</b> Foo Bar'
|
||||
agenda.save()
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day))
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "<b>bar's</b> Foo Bar"
|
||||
assert '<b>bar's</b> Foo Bar' in resp
|
||||
|
||||
# create a shorter meeting type, this will change the table CSS class
|
||||
# (and visually this will give more room for events)
|
||||
meetingtype = MeetingType(agenda=agenda, label='Baz', duration=15)
|
||||
|
@ -1354,15 +1370,27 @@ def test_agenda_month_view(app, admin_user, manager_user, api_user):
|
|||
booking_url = resp.json['data'][0]['api']['fillslot_url']
|
||||
booking_url2 = resp.json['data'][2]['api']['fillslot_url']
|
||||
booking = app.post(booking_url)
|
||||
booking_2 = app.post_json(booking_url2, params={'label': 'foo book', 'user': 'bar', 'url': 'http://baz/'})
|
||||
booking_2 = app.post_json(
|
||||
booking_url2, params={'label': 'foo book', 'user_last_name': "bar's", 'url': 'http://baz/'}
|
||||
)
|
||||
|
||||
app.reset()
|
||||
login(app)
|
||||
date = Booking.objects.all()[0].event.start_datetime
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/' % (agenda.id, date.year, date.month))
|
||||
assert resp.text.count('<div class="booking" style="left:1.0%;height:33.0%;') == 2 # booking cells
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "foo book - bar's"
|
||||
assert 'foo book - bar's' in resp
|
||||
assert len(resp.pyquery.find('span.desk')) == 0
|
||||
|
||||
agenda.booking_user_block_template = '<b>{{ booking.user_name }}</b> Foo Bar'
|
||||
agenda.save()
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/' % (agenda.id, date.year, date.month))
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "<b>bar's</b> Foo Bar"
|
||||
assert '<b>bar's</b> Foo Bar' in resp
|
||||
|
||||
desk = Desk.objects.create(agenda=agenda, label='Desk B')
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/' % (agenda.id, date.year, date.month))
|
||||
assert len(resp.pyquery.find('span.desk')) == 2
|
||||
|
@ -1853,14 +1881,30 @@ def test_virtual_agenda_day_view(app, admin_user, manager_user):
|
|||
meeting_type=meetingtype2,
|
||||
start_datetime=now().replace(hour=hour, minute=minute),
|
||||
)
|
||||
Booking.objects.create(event=event)
|
||||
Booking.objects.create(event=event, label='foo', user_last_name="bar's")
|
||||
|
||||
date = Booking.objects.all()[0].event.start_datetime
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day))
|
||||
assert resp.text.count('div class="booking') == 4
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "foo - bar's"
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[2].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[3].text.strip() == "foo - bar's"
|
||||
assert 'foo - bar's' in resp
|
||||
assert 'hourspan-2' in resp.text # table CSS class
|
||||
assert 'height: 50%; top: 0%;' in resp.text # booking cells
|
||||
|
||||
real_agenda_1.booking_user_block_template = '<b>{{ booking.user_name }}</b> Foo Bar'
|
||||
real_agenda_1.save()
|
||||
real_agenda_2.booking_user_block_template = '<b>{{ booking.user_name }}</b> Bar Foo'
|
||||
real_agenda_2.save()
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day))
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "<b>bar's</b> Bar Foo"
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[2].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[3].text.strip() == "<b>bar's</b> Bar Foo"
|
||||
assert '<b>bar's</b> Bar Foo' in resp
|
||||
|
||||
# create a shorter meeting type, this will change the table CSS class
|
||||
# (and visually this will give more room for events)
|
||||
MeetingType.objects.create(agenda=real_agenda_1, label='Baz', duration=15)
|
||||
|
@ -1986,7 +2030,7 @@ def test_virtual_agenda_month_view(app, admin_user):
|
|||
meeting_type=meetingtype2,
|
||||
start_datetime=now().replace(hour=hour, minute=minute),
|
||||
)
|
||||
Booking.objects.create(event=event)
|
||||
Booking.objects.create(event=event, label='foo', user_last_name="bar's")
|
||||
|
||||
date = Booking.objects.all()[0].event.start_datetime
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/' % (agenda.id, date.year, date.month))
|
||||
|
@ -1994,6 +2038,22 @@ def test_virtual_agenda_month_view(app, admin_user):
|
|||
assert (
|
||||
resp.text.count('<div class="booking" style="left:50.0%;height:50.0%;min-height:50.0%;') == 2
|
||||
) # booking cells
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "foo - bar's"
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[2].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[3].text.strip() == "foo - bar's"
|
||||
assert 'foo - bar's' in resp
|
||||
|
||||
real_agenda_1.booking_user_block_template = '<b>{{ booking.user_name }}</b> Foo Bar'
|
||||
real_agenda_1.save()
|
||||
real_agenda_2.booking_user_block_template = '<b>{{ booking.user_name }}</b> Bar Foo'
|
||||
real_agenda_2.save()
|
||||
resp = app.get('/manage/agendas/%s/%d/%d/' % (agenda.id, date.year, date.month))
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "<b>bar's</b> Bar Foo"
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[2].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[3].text.strip() == "<b>bar's</b> Bar Foo"
|
||||
assert '<b>bar's</b> Bar Foo' in resp
|
||||
|
||||
# cancel a booking
|
||||
booking = Booking.objects.first()
|
||||
|
|
|
@ -102,16 +102,29 @@ def test_resource_day_view(app, admin_user):
|
|||
start_datetime=now().replace(hour=hour, minute=minute),
|
||||
)
|
||||
event.resources.add(resource)
|
||||
Booking.objects.create(event=event)
|
||||
if hour == 10:
|
||||
Booking.objects.create(event=event)
|
||||
else:
|
||||
Booking.objects.create(event=event, label='foo', user_last_name="bar's")
|
||||
|
||||
with CaptureQueriesContext(connection) as ctx:
|
||||
resp = app.get('/manage/resource/%s/%d/%d/%d/' % (resource.pk, today.year, today.month, today.day))
|
||||
assert len(ctx.captured_queries) == 7
|
||||
assert resp.text.count('div class="booking') == 2
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "foo - bar's"
|
||||
assert 'foo - bar's' in resp
|
||||
assert 'hourspan-2' in resp.text # table CSS class
|
||||
assert 'height: 50%; top: 0%;' in resp.text # booking cells
|
||||
assert 'height: 50%; top: 50%;' in resp.text # booking cells
|
||||
|
||||
agenda.booking_user_block_template = '<b>{{ booking.user_name }}</b> Foo Bar'
|
||||
agenda.save()
|
||||
resp = app.get('/manage/resource/%s/%d/%d/%d/' % (resource.pk, today.year, today.month, today.day))
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "<b>bar's</b> Foo Bar"
|
||||
assert '<b>bar's</b> Foo Bar' in resp
|
||||
|
||||
# create a shorter meeting type, this will change the table CSS class
|
||||
# (and visually this will give more room for events)
|
||||
meetingtype = MeetingType.objects.create(agenda=agenda, label='Baz', duration=15)
|
||||
|
@ -240,13 +253,26 @@ def test_resource_month_view(app, admin_user):
|
|||
start_datetime=now().replace(hour=hour, minute=minute),
|
||||
)
|
||||
event.resources.add(resource)
|
||||
Booking.objects.create(event=event)
|
||||
if hour == 10:
|
||||
Booking.objects.create(event=event)
|
||||
else:
|
||||
Booking.objects.create(event=event, label='foo', user_last_name="bar's")
|
||||
|
||||
today = datetime.date.today()
|
||||
with CaptureQueriesContext(connection) as ctx:
|
||||
resp = app.get('/manage/resource/%s/%s/%s/' % (resource.pk, today.year, today.month))
|
||||
assert len(ctx.captured_queries) == 8
|
||||
assert resp.text.count('<div class="booking" style="height:33.0%;') == 2 # booking cells
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == 'booked'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "foo - bar's"
|
||||
assert 'foo - bar's' in resp
|
||||
|
||||
agenda.booking_user_block_template = '<b>{{ booking.user_name }}</b> Foo Bar'
|
||||
agenda.save()
|
||||
resp = app.get('/manage/resource/%s/%s/%s/' % (resource.pk, today.year, today.month))
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[0].text.strip() == '<b></b> Foo Bar'
|
||||
assert resp.pyquery.find('div.booking a').not_('.cancel')[1].text.strip() == "<b>bar's</b> Foo Bar"
|
||||
assert '<b>bar's</b> Foo Bar' in resp
|
||||
|
||||
# cancel booking
|
||||
booking = Booking.objects.first()
|
||||
|
|
Loading…
Reference in New Issue