From 97dac51a52cfacb6b469add108ebe4c77797aa39 Mon Sep 17 00:00:00 2001 From: FreneticScribbler Date: Mon, 15 May 2023 00:36:57 +0100 Subject: [PATCH] Add ability to edit checkins, more validation --- RIGS/forms.py | 7 +++ RIGS/models.py | 7 ++- RIGS/templates/event_detail.html | 38 ++++++++++++++ RIGS/templates/hs/event_checklist_detail.html | 31 ----------- RIGS/templates/hs/eventcheckin_form.html | 52 +++++++++++-------- .../partials/event_detail_buttons.html | 5 +- RIGS/urls.py | 4 ++ RIGS/views/hs.py | 33 +++++++++++- templates/base.html | 2 +- 9 files changed, 122 insertions(+), 57 deletions(-) diff --git a/RIGS/forms.py b/RIGS/forms.py index 5b5b835b..59e9eb01 100644 --- a/RIGS/forms.py +++ b/RIGS/forms.py @@ -232,3 +232,10 @@ class EventCheckInForm(forms.ModelForm): class Meta: model = models.EventCheckIn fields = '__all__' + exclude = ['end_time'] + + +class EditCheckInForm(forms.ModelForm): + class Meta: + model = models.EventCheckIn + fields = '__all__' diff --git a/RIGS/models.py b/RIGS/models.py index dc746f17..df666fad 100644 --- a/RIGS/models.py +++ b/RIGS/models.py @@ -82,7 +82,8 @@ class Profile(AbstractUser): return self.name def current_event(self): - return EventCheckIn.objects.filter(person=self).latest('time') or None + q = EventCheckIn.objects.filter(person=self, end_time=None) + return q.latest('time') if q.exists() else None class ContactableManager(models.Manager): @@ -919,6 +920,10 @@ class EventCheckIn(models.Model): vehicle = models.CharField(max_length=100, blank=True) 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.") + def active(self): return end_time is not None diff --git a/RIGS/templates/event_detail.html b/RIGS/templates/event_detail.html index b04089fb..d1c873d7 100644 --- a/RIGS/templates/event_detail.html +++ b/RIGS/templates/event_detail.html @@ -1,6 +1,7 @@ {% extends request.is_ajax|yesno:"base_ajax.html,base_rigs.html" %} {% load markdown_tags %} +{% load button from filters %} {% block content %}
@@ -52,6 +53,43 @@
+ {% if not event.dry_hire %} +
+
+
Crew Record
+
+ + + + + + + + + + + + + {% for crew in object.crew.all %} + + + + + + + + + {% empty %} + + + + {% endfor %} + +
CrewmemberVehicleStart TimeRoleEnd Time
{{crew.person}}{{crew.vehicle|default:"None"}}{{crew.time}}{{crew.role}}{% if crew.end_time %}{{crew.end_time}}{% else %}{% endif %}{% if crew.end_time %}{% if crew.person.pk == request.user.pk or crew.event.mic.pk == request.user.pk %}{% button 'edit' 'edit_checkin' crew.pk clazz='btn-sm modal-href' %}{% endif %}{%endif%}
Apparently this event happened by magic...
+
+
+ {% endif %} +
{% if not request.is_ajax and perms.RIGS.view_event %}
{% include 'partials/event_detail_buttons.html' %} diff --git a/RIGS/templates/hs/event_checklist_detail.html b/RIGS/templates/hs/event_checklist_detail.html index 6e4409c8..705e0209 100644 --- a/RIGS/templates/hs/event_checklist_detail.html +++ b/RIGS/templates/hs/event_checklist_detail.html @@ -68,37 +68,6 @@
-
-
Crew Record
-
- - - - - - - - - - - - {% for crew in object.event.crew.all %} - - - - - - - - {% empty %} - - - - {% endfor %} - -
CrewmemberVehicleStart TimeRoleEnd Time
{{crew.person}}{{crew.vehicle|default:"None"}}{{crew.time}}{{crew.role}}{{crew.end_time}}
Apparently this event happened by magic...
-
-
{% button 'edit' url='ec_edit' pk=object.pk %} {% button 'view' url='event_detail' pk=object.pk text="Event" %} diff --git a/RIGS/templates/hs/eventcheckin_form.html b/RIGS/templates/hs/eventcheckin_form.html index a96e8320..504b6e40 100644 --- a/RIGS/templates/hs/eventcheckin_form.html +++ b/RIGS/templates/hs/eventcheckin_form.html @@ -6,7 +6,7 @@ {% block content %}
{% include 'form_errors.html' %} -
+
- -
- - - -
-

Other (enter text)

-
-
- {% render_field form.role class+="form-control" %} + +
+
+ + + +
+
+ {% render_field form.role class+="form-control" placeholder="Other (enter text)" %} +
- -
- - -
-

Other (enter text)

-
-
- {% render_field form.vehicle class+="form-control" %} + +
+
+ + +
+
+ {% render_field form.vehicle class+="form-control" placeholder="Other (enter text)" %} +
+ {% if edit %} +
+ +
+ {% render_field form.end_time class+="form-control" %} +
+
+ {% endif %} {% if not request.is_ajax %}
@@ -57,6 +66,7 @@ {% block footer %}
- +
{% endblock %} diff --git a/RIGS/templates/partials/event_detail_buttons.html b/RIGS/templates/partials/event_detail_buttons.html index f52bd954..00695818 100644 --- a/RIGS/templates/partials/event_detail_buttons.html +++ b/RIGS/templates/partials/event_detail_buttons.html @@ -49,6 +49,9 @@ {% endif %} Subhire Insurance Form - Check In + + {% if not event.dry_hire %} + Check In + {% endif %} {% endif %}
diff --git a/RIGS/urls.py b/RIGS/urls.py index 68c4fbc3..6a3dd971 100644 --- a/RIGS/urls.py +++ b/RIGS/urls.py @@ -103,6 +103,10 @@ urlpatterns = [ path('event//checkin/', permission_required_with_403('RIGS.add_eventcheckin')(views.EventCheckIn.as_view()), name='event_checkin'), + path('event/checkout/', permission_required_with_403('RIGS.change_eventcheckin')(views.EventCheckOut.as_view()), + name='event_checkout'), + path('event//checkin/edit/', permission_required_with_403('RIGS.change_eventcheckin')(views.EventCheckInEdit.as_view()), + name='edit_checkin'), # Finance path('invoice/', permission_required_with_403('RIGS.view_invoice')(views.InvoiceIndex.as_view()), diff --git a/RIGS/views/hs.py b/RIGS/views/hs.py index a54348fb..5b48988a 100644 --- a/RIGS/views/hs.py +++ b/RIGS/views/hs.py @@ -8,7 +8,7 @@ from reversion import revisions as reversion from RIGS import models, forms from RIGS.views.rigboard import get_related -from PyRIGS.views import PrintView +from PyRIGS.views import PrintView, ModalURLMixin class HSCreateView(generic.CreateView): @@ -228,14 +228,43 @@ class RAPrint(PrintView): return context -class EventCheckIn(generic.CreateView): +class EventCheckIn(generic.CreateView, ModalURLMixin): model = models.EventCheckIn template_name = 'hs/eventcheckin_form.html' form_class = forms.EventCheckInForm + def get_success_url(self): + return self.get_close_url('event_detail', 'event_detail') # Well, that's one way of doing that...! + 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'Check In to Event {context["event"].display_id}' # get_related(context['form'], context) return context + + +class EventCheckInEdit(generic.UpdateView, ModalURLMixin): + model = models.EventCheckIn + template_name = 'hs/eventcheckin_form.html' + form_class = forms.EditCheckInForm + + def get_success_url(self): + return self.get_close_url('event_detail', 'event_detail') # Well, that's one way of doing that...! + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['event'] = self.object.event + context['page_title'] = f'Edit Check In for Event {context["event"].display_id}' + context['edit'] = True + # get_related(context['form'], context) + return context + + +class EventCheckOut(generic.RedirectView): + def get_redirect_url(self, *args, **kwargs): + checkin = self.request.user.current_event() + if checkin: + checkin.end_time = timezone.now() + checkin.save() + return reverse_lazy('event_detail', kwargs={'pk': checkin.event.pk}) diff --git a/templates/base.html b/templates/base.html index 6c40bf1e..562e0c12 100644 --- a/templates/base.html +++ b/templates/base.html @@ -31,7 +31,7 @@ {% block navbar %} {% if request.user.current_event %} -
You are currently checked in to {{request.user.current_event.event}}Check Out
+
You are currently checked in to {{request.user.current_event.event}}Check Out
{% endif %}