manager: display placeholder for leased bookings (#82774)
This commit is contained in:
parent
14b7de35cc
commit
2831272e56
|
@ -201,6 +201,18 @@ table.agenda-table {
|
|||
text-align: center;
|
||||
}
|
||||
&.booking {
|
||||
&.lease {
|
||||
background:
|
||||
repeating-linear-gradient(
|
||||
135deg,
|
||||
hsla(10, 10%, 75%, 0.7) 0,
|
||||
hsla(10, 10%, 80%, 0.55) 10px,
|
||||
transparent 11px,
|
||||
transparent 20px);
|
||||
// color: currentColor;
|
||||
color: hsla(0, 0%, 0%, 0.7);
|
||||
}
|
||||
|
||||
left: 0;
|
||||
color: hsl(210, 84%, 40%);
|
||||
padding: 1ex;
|
||||
|
@ -562,6 +574,18 @@ div.agenda-settings .pk-tabs--container {
|
|||
|
||||
#event_details {
|
||||
margin: 1em 0;
|
||||
.objects-list .lease {
|
||||
background:
|
||||
repeating-linear-gradient(
|
||||
135deg,
|
||||
hsla(10, 10%, 75%, 0.7) 0,
|
||||
hsla(10, 10%, 80%, 0.55) 10px,
|
||||
transparent 11px,
|
||||
transparent 20px);
|
||||
}
|
||||
.objects-list .lease span {
|
||||
padding: 0 0.5ex 0 2ex;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
|
|
@ -28,12 +28,16 @@
|
|||
|
||||
<ul class="objects-list single-links">
|
||||
{% for booking in booked %}
|
||||
<li>
|
||||
<a {% if booking.get_backoffice_url %}href="{{ booking.get_backoffice_url }}"{% endif %}>{{ booking.get_user_block }}, {{ booking.creation_datetime|date:"DATETIME_FORMAT" }}</a>
|
||||
{% if not booking.primary_booking %}
|
||||
<a rel="popup" class="delete" href="{% url 'chrono-manager-booking-cancel' pk=agenda.id booking_pk=booking.id %}?next={{ request.path }}">{% trans "Cancel" %}</a>
|
||||
<li{% if booking.lease %} class="lease"{% endif %}>
|
||||
{% if booking.lease %}
|
||||
<span>{% trans "Currently being booked..." %}</span>
|
||||
{% else %}
|
||||
<a class="delete disabled" title="{% trans "Can not cancel a secondary booking" %}" href="#">{% trans "Cancel" %}</a>
|
||||
<a {% if booking.get_backoffice_url %}href="{{ booking.get_backoffice_url }}"{% endif %}>{{ booking.get_user_block }}, {{ booking.creation_datetime|date:"DATETIME_FORMAT" }}</a>
|
||||
{% if not booking.primary_booking %}
|
||||
<a rel="popup" class="delete" href="{% url 'chrono-manager-booking-cancel' pk=agenda.id booking_pk=booking.id %}?next={{ request.path }}">{% trans "Cancel" %}</a>
|
||||
{% else %}
|
||||
<a class="delete disabled" title="{% trans "Can not cancel a secondary booking" %}" href="#">{% trans "Cancel" %}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
@ -53,7 +57,7 @@
|
|||
<div>
|
||||
<ul class="objects-list single-links">
|
||||
{% for booking in waiting %}
|
||||
<li><a {% if booking.get_backoffice_url %}href="{{ booking.get_backoffice_url }}"{% endif %}>{{ booking.get_user_block }}, {{ booking.creation_datetime|date:"DATETIME_FORMAT" }}</a></li>
|
||||
<li{% if booking.lease %} class="lease"{% endif %}><a {% if booking.get_backoffice_url %}href="{{ booking.get_backoffice_url }}"{% endif %}>{% if booking.lease %}{% trans "Currently being booked..." %}{% else %}{{ booking.get_user_block }}, {{ booking.creation_datetime|date:"DATETIME_FORMAT" }}{% endif %}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -38,12 +38,16 @@
|
|||
{% endif %}
|
||||
|
||||
{% for booking in desk_info.bookings %}
|
||||
<div class="booking{% if booking.color %} booking-color-{{ booking.color.index }}{% endif %}"
|
||||
<div class="booking{% if booking.color %} booking-color-{{ booking.color.index }}{% endif %}{% if booking.lease %} lease{% 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.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 %}
|
||||
{% if booking.lease %}
|
||||
{% trans "Currently being booked..." %}
|
||||
{% else %}
|
||||
<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 %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
|
|
|
@ -31,12 +31,16 @@
|
|||
{% endfor %}
|
||||
|
||||
{% 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" }}%;">
|
||||
<div class="booking{% if slot.booking.color %} booking-color-{{ slot.booking.color.index }}{% endif %}{% if slot.booking.lease %} lease{% 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.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 %}
|
||||
{% if slot.booking.lease %}
|
||||
{% trans "Currently being booked..." %}
|
||||
{% else %}
|
||||
<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 %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
@ -316,7 +316,7 @@ class ResourceDayView(DateMixin, DayArchiveView):
|
|||
queryset = (
|
||||
self.resource.event_set.all()
|
||||
.select_related('meeting_type', 'agenda')
|
||||
.prefetch_related('booking_set')
|
||||
.prefetch_related('booking_set', 'booking_set__lease')
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
@ -432,7 +432,7 @@ class ResourceWeekMonthMixin:
|
|||
queryset = (
|
||||
self.resource.event_set.all()
|
||||
.select_related('meeting_type', 'agenda')
|
||||
.prefetch_related('booking_set')
|
||||
.prefetch_related('booking_set', 'booking_set__lease')
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
@ -1359,7 +1359,7 @@ class AgendaDateView(DateMixin, ViewableAgendaMixin):
|
|||
queryset = (
|
||||
Event.objects.filter(agenda__virtual_agendas=self.agenda)
|
||||
.select_related('meeting_type', 'agenda')
|
||||
.prefetch_related('booking_set')
|
||||
.prefetch_related('booking_set', 'booking_set__lease')
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
@ -2770,12 +2770,13 @@ class EventDetailView(ViewableAgendaMixin, DetailView):
|
|||
context = super().get_context_data(**kwargs)
|
||||
context['user_can_manage'] = self.agenda.can_be_managed(self.request.user)
|
||||
event = self.object
|
||||
bookings = event.booking_set.select_related('lease')
|
||||
context['booked'] = (
|
||||
event.booking_set.filter(cancellation_datetime__isnull=True, in_waiting_list=False)
|
||||
bookings.filter(cancellation_datetime__isnull=True, in_waiting_list=False)
|
||||
.prefetch_related('user_checks')
|
||||
.order_by('creation_datetime')
|
||||
)
|
||||
context['waiting'] = event.booking_set.filter(
|
||||
context['waiting'] = bookings.filter(
|
||||
cancellation_datetime__isnull=True, in_waiting_list=True
|
||||
).order_by('creation_datetime')
|
||||
event.present_count = len([b for b in context['booked'] if b.user_check and b.user_check.presence])
|
||||
|
|
|
@ -1046,7 +1046,7 @@ def test_agenda_day_view(app, admin_user, manager_user, api_user):
|
|||
resp = app.get(
|
||||
'/manage/agendas/%s/day/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day), status=200
|
||||
)
|
||||
assert len(ctx.captured_queries) == 14
|
||||
assert len(ctx.captured_queries) == 15
|
||||
# day is displaying rows from 10am to 6pm,
|
||||
# opening hours, 10am to 1pm gives top: 300%
|
||||
# calendar exception, 1pm to 3pm gives heigh: 200%
|
||||
|
@ -2635,7 +2635,7 @@ def test_virtual_agenda_day_view(app, admin_user, manager_user):
|
|||
resp = app.get(
|
||||
'/manage/agendas/%s/day/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day), status=200
|
||||
)
|
||||
assert len(ctx.captured_queries) == 16
|
||||
assert len(ctx.captured_queries) == 17
|
||||
# day is displaying rows from 10am to 6pm,
|
||||
# opening hours, 10am to 1pm gives top: 300%
|
||||
# rest of the day, 1pm to 6(+1)pm gives 600%
|
||||
|
@ -4030,3 +4030,40 @@ def test_agenda_today_button(app, admin_user):
|
|||
|
||||
resp = app.get('/manage/agendas/%s/week/%s/%s/%s/' % (agenda.pk, today.year, today.month, today.day))
|
||||
assert 'Today' not in resp.pyquery('a.active').text()
|
||||
|
||||
|
||||
def test_meeting_agenda_lease_display(app, admin_user, manager_user, api_user):
|
||||
agenda = Agenda.objects.create(label='New Example', kind='meetings')
|
||||
desk = Desk.objects.create(agenda=agenda, label='New Desk')
|
||||
meetingtype = MeetingType.objects.create(agenda=agenda, label='Bar', duration=30)
|
||||
today = datetime.date.today()
|
||||
TimePeriod.objects.create(
|
||||
desk=desk, weekday=today.weekday(), start_time=datetime.time(10, 0), end_time=datetime.time(18, 30)
|
||||
)
|
||||
|
||||
# Create a leased booking
|
||||
app.reset()
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
resp = app.get('/api/agenda/%s/meetings/%s/datetimes/' % (agenda.slug, meetingtype.slug))
|
||||
booking_url = resp.json['data'][0]['api']['fillslot_url']
|
||||
app.post(booking_url, params={'lock_code': 'ABCD'})
|
||||
|
||||
date = Booking.objects.all()[0].event.start_datetime
|
||||
app.reset()
|
||||
login(app)
|
||||
|
||||
# Display agenda on day of the leased booking
|
||||
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day))
|
||||
assert len(resp.pyquery('.booking')) == 1
|
||||
assert len(resp.pyquery('.booking.lease')) == 1
|
||||
assert 'Currently being booked...' in resp.pyquery('.booking.lease').text()
|
||||
|
||||
resp = app.get('/manage/agendas/%s/week/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day))
|
||||
assert len(resp.pyquery('.booking')) == 1
|
||||
assert len(resp.pyquery('.booking.lease')) == 1
|
||||
assert 'Currently being booked...' in resp.pyquery('.booking.lease').text()
|
||||
|
||||
resp = app.get('/manage/agendas/%s/month/%d/%d/%d/' % (agenda.id, date.year, date.month, date.day))
|
||||
assert len(resp.pyquery('.booking')) == 1
|
||||
assert len(resp.pyquery('.booking.lease')) == 1
|
||||
assert 'Currently being booked...' in resp.pyquery('.booking.lease').text()
|
||||
|
|
|
@ -11,7 +11,7 @@ from django.test import override_settings
|
|||
from django.test.utils import CaptureQueriesContext
|
||||
from webtest import Upload
|
||||
|
||||
from chrono.agendas.models import Agenda, Booking, Desk, Event, EventsType, Subscription
|
||||
from chrono.agendas.models import Agenda, Booking, Desk, Event, EventsType, Lease, Subscription
|
||||
from chrono.utils.lingo import CheckType
|
||||
from chrono.utils.timezone import localtime, make_aware, now
|
||||
from tests.utils import login
|
||||
|
@ -3381,3 +3381,25 @@ def test_duplicate_event_creates_recurrences(app, admin_user):
|
|||
|
||||
event_recurrence = duplicate.recurrences.first()
|
||||
app.get(f'/manage/agendas/{agenda.pk}/events/{event_recurrence.pk}/duplicate', status=404)
|
||||
|
||||
|
||||
@pytest.mark.freeze_time('2022-05-24')
|
||||
def test_event_detail_lease_display(app, admin_user):
|
||||
agenda = Agenda.objects.create(label='Events', kind='events')
|
||||
event = Event.objects.create(
|
||||
label='xyz',
|
||||
start_datetime=now() + datetime.timedelta(days=1),
|
||||
places=10,
|
||||
waiting_list_places=2,
|
||||
agenda=agenda,
|
||||
)
|
||||
booking1 = Booking.objects.create(event=event, user_last_name="User's 1")
|
||||
booking2 = Booking.objects.create(event=event, user_last_name='User 2', in_waiting_list=True)
|
||||
Lease.objects.create(booking=booking1, lock_code='ABCD')
|
||||
Lease.objects.create(booking=booking2, lock_code='ABCD')
|
||||
|
||||
login(app)
|
||||
resp = app.get('/manage/agendas/%d/events/%d/' % (agenda.pk, event.pk))
|
||||
assert 'Bookings (1/10)' in resp.text
|
||||
assert 'Waiting List (1/2): 1 remaining place' in resp.text
|
||||
assert resp.text.count('Currently being booked...') == 2
|
||||
|
|
|
@ -126,7 +126,7 @@ def test_resource_day_view(app, admin_user):
|
|||
resp = app.get(
|
||||
'/manage/resource/%s/day/%d/%d/%d/' % (resource.pk, today.year, today.month, today.day)
|
||||
)
|
||||
assert len(ctx.captured_queries) == 7
|
||||
assert len(ctx.captured_queries) == 8
|
||||
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"
|
||||
|
@ -279,7 +279,7 @@ def test_resource_week_view(app, admin_user):
|
|||
resp = app.get(
|
||||
'/manage/resource/%s/week/%s/%s/%s/' % (resource.pk, today.year, today.month, today.day)
|
||||
)
|
||||
assert len(ctx.captured_queries) == 8
|
||||
assert len(ctx.captured_queries) == 9
|
||||
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"
|
||||
|
@ -625,7 +625,7 @@ def test_resource_month_view(app, admin_user):
|
|||
resp = app.get(
|
||||
'/manage/resource/%s/month/%s/%s/%s/' % (resource.pk, today.year, today.month, today.day)
|
||||
)
|
||||
assert len(ctx.captured_queries) == 8
|
||||
assert len(ctx.captured_queries) == 9
|
||||
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"
|
||||
|
|
Loading…
Reference in New Issue