Basic checkin/out logic complete

This commit is contained in:
2023-05-15 01:12:04 +01:00
parent 97dac51a52
commit 417ec8ff3d
7 changed files with 69 additions and 9 deletions

View File

@@ -200,7 +200,6 @@ class EventChecklistForm(forms.ModelForm):
related_models = {
'venue': models.Venue,
'power_mic': models.Profile,
}
class Meta:

View File

@@ -482,6 +482,15 @@ class Event(models.Model, RevisionMixin):
else:
return bool(self.purchase_order)
@property
def can_check_in(self):
earliest = self.earliest_time
if isinstance(self.earliest_time, datetime.date):
earliest = datetime.datetime.combine(self.start_date, datetime.time(00, 00))
tz = pytz.timezone(settings.TIME_ZONE)
earliest = tz.localize(earliest)
return not self.dry_hire and earliest <= timezone.now()
objects = EventManager()
def get_absolute_url(self):
@@ -921,8 +930,11 @@ class EventCheckIn(models.Model):
end_time = models.DateTimeField(null=True)
def clean(self):
if self.end_time < self.time:
raise ValidationError("May not check out before you've checked in. Please invent time travel and retry.")
sass = " Please invent time travel and retry."
if self.time > timezone.now():
raise ValidationError("May not check in in the future." + sass)
if self.end_time and self.end_time < self.time:
raise ValidationError("May not check out before you've checked in." + sass)
def active(self):
return end_time is not None

View File

@@ -2,6 +2,7 @@
{% load markdown_tags %}
{% load button from filters %}
{% load static %}
{% block content %}
<div class="row my-3 py-3">
@@ -53,7 +54,7 @@
</div>
</div>
</div>
{% if not event.dry_hire %}
{% if event.can_check_in %}
<div class="col-sm-12">
<div class="card mt-3">
<div class="card-header">Crew Record</div>
@@ -66,10 +67,10 @@
<th scope="col">Start Time</th>
<th scope="col">Role</th>
<th scope="col">End Time</th>
<th></th>
<th scope="col">{% if self.request.user.pk is form.event.mic.pk %}<a href="{% url 'event_checkin_override' event.pk %}" class="btn btn-sm btn-success"><span class="fas fa-plus"></span> Add</a>{% endif %}</th>
</tr>
</thead>
<tbody id="crewmemberst">
<tbody id="crewmembers">
{% for crew in object.crew.all %}
<tr>
<td>{{crew.person}}</td>
@@ -81,7 +82,7 @@
</tr>
{% empty %}
<tr>
<td colspan="5" class="text-center bg-warning">Apparently this event happened by magic...</td>
<td colspan="6" class="text-center bg-warning">Apparently this event happened by magic...</td>
</tr>
{% endfor %}
</tbody>

View File

@@ -3,14 +3,47 @@
{% load static %}
{% load button from filters %}
{% block css %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'css/selects.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static 'css/easymde.min.css' %}">
{% endblock %}
{% block preload_js %}
{{ block.super }}
<script src="{% static 'js/selects.js' %}"></script>
<script src="{% static 'js/easymde.min.js' %}"></script>
{% endblock %}
{% block js %}
{{ block.super }}
<script src="{% static 'js/autocompleter.js' %}"></script>
<script src="{% static 'js/interaction.js' %}"></script>
<script src="{% static 'js/tooltip.js' %}"></script>
{% endblock %}
{% block content %}
<div class="col-12">
{% include 'form_errors.html' %}
<form id="checkin" role="form" method="POST" action="{{ form.action|default:request.path }}">
<input type="hidden" name="{{ form.event.name }}" id="{{ form.event.id_for_label }}"
value="{{event.pk}}"/>
{% if not request.is_ajax and self.request.user.pk is form.event.mic.pk %}
<div class="form-group">
<label for="{{ form.person.id_for_label }}"
class="col-sm-4 col-form-label">{{ form.person.label }}</label>
<div class="col-sm-8">
<select id="{{ form.person.id_for_label }}" name="{{ form.person.name }}" class="px-0 selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials">
{% if person %}
<option value="{{form.person.value}}" selected="selected" >{{ person.name }}</option>
{% endif %}
</select>
</div>
</div>
{% else %}
<input type="hidden" name="{{ form.person.name }}" id="{{ form.person.id_for_label }}"
value="{{request.user.pk}}"/>
{% endif %}
{% csrf_token %}
<div class="form-group">
<label for="{{ form.time.id_for_label }}"
@@ -44,7 +77,7 @@
</div>
</div>
</div>
{% if edit %}
{% if edit or manual %}
<div class="form-group">
<label for="{{ form.end_time.id_for_label }}"
class="col-sm-4 col-form-label">End Time</label>

View File

@@ -50,7 +50,7 @@
<a href="https://docs.google.com/forms/d/e/1FAIpQLSf-TBOuJZCTYc2L8DWdAaC3_Werq0ulsUs8-6G85I6pA9WVsg/viewform" class="btn btn-danger"><span class="fas fa-file-invoice-dollar"></span> <span class="d-none d-sm-inline">Subhire Insurance Form</span></a>
{% if not event.dry_hire %}
{% if event.can_check_in %}
<a href="{% url 'event_checkin' event.pk %}" class="btn btn-success modal-href {% if request.user.current_event %}disabled{%endif%}"><span class="fas fa-user-clock"></span> <span class="d-none d-sm-inline">Check In</span></a>
{% endif %}
{% endif %}

View File

@@ -107,6 +107,8 @@ urlpatterns = [
name='event_checkout'),
path('event/<int:pk>/checkin/edit/', permission_required_with_403('RIGS.change_eventcheckin')(views.EventCheckInEdit.as_view()),
name='edit_checkin'),
path('event/<int:pk>/checkin/add/', permission_required_with_403('RIGS.add_eventcheckin')(views.EventCheckInOverride.as_view()),
name='event_checkin_override'),
# Finance
path('invoice/', permission_required_with_403('RIGS.view_invoice')(views.InvoiceIndex.as_view()),

View File

@@ -244,6 +244,19 @@ class EventCheckIn(generic.CreateView, ModalURLMixin):
return context
class EventCheckInOverride(generic.CreateView):
model = models.EventCheckIn
template_name = 'hs/eventcheckin_form.html'
form_class = forms.EditCheckInForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['event'] = models.Event.objects.get(pk=self.kwargs.get('pk'))
context['page_title'] = f'Manually add Check In to Event {context["event"].display_id}'
context['manual'] = True
return context
class EventCheckInEdit(generic.UpdateView, ModalURLMixin):
model = models.EventCheckIn
template_name = 'hs/eventcheckin_form.html'